From 14efa5b56165e89bf4a41d716b0d39e5546e8443 Mon Sep 17 00:00:00 2001 From: skudasov Date: Thu, 19 Jun 2025 14:00:41 +0200 Subject: [PATCH] wip: remove legacy --- .../myproject/fork_plus_offchain.toml | 10 +- .../myproject/fork_plus_offchain_test.go | 19 +- lib/blockchain/ethereum.go | 68 - lib/client/mockserver.go | 315 - lib/client/mockserver_test.go | 131 - lib/client/postgres.go | 73 - lib/docker/test_env/mockserver.go | 148 - lib/docker/test_env/mockserver_test.go | 48 - lib/docker/test_env/parrot.go | 9 - lib/go.mod | 72 +- lib/go.sum | 212 +- lib/k8s/Dockerfile | 7 - lib/k8s/Dockerfile.base | 42 - lib/k8s/README.md | 3 - lib/k8s/cdk8s.yaml | 4 - lib/k8s/chaos/experiments.go | 157 - lib/k8s/client/chaos.go | 152 - lib/k8s/client/client.go | 572 - lib/k8s/client/cmd.go | 79 - lib/k8s/client/cmd_test.go | 45 - lib/k8s/client/converter.go | 73 - lib/k8s/client/forwarder.go | 204 - lib/k8s/config/{overrides.go => config.go} | 0 lib/k8s/config/overrides_test.go | 59 - lib/k8s/e2e/common/test_common.go | 489 - lib/k8s/e2e/local-runner/envs_test.go | 82 - .../remote-runner/remote_runner_envs_test.go | 195 - lib/k8s/environment/artifacts.go | 177 - lib/k8s/environment/environment.go | 1459 - lib/k8s/environment/runner.go | 471 - lib/k8s/examples/clones/clones.go | 53 - lib/k8s/examples/concurrent/env_test.go | 36 - lib/k8s/examples/coverage/Dockerfile | 5 - lib/k8s/examples/coverage/Dockerfile.target | 8 - lib/k8s/examples/coverage/entrypoint.sh | 2 - lib/k8s/examples/coverage/env.go | 27 - lib/k8s/examples/deployment_part/cmd/env.go | 38 - lib/k8s/examples/deployment_part/sol.go | 117 - .../deployment_part_cdk8s/blockscout.go | 220 - .../examples/deployment_part_cdk8s/cmd/env.go | 21 - lib/k8s/examples/dump/env.go | 19 - lib/k8s/examples/link/Dockerfile | 62 - lib/k8s/examples/link/link_test.go | 193 - lib/k8s/examples/modify_cdk8s/env.go | 42 - lib/k8s/examples/modify_helm/env.go | 41 - lib/k8s/examples/multistage/env.go | 36 - lib/k8s/examples/multistage/someData.txt | 1 - lib/k8s/examples/quick-debug/env.go | 22 - lib/k8s/examples/remote-test-runner/env.go | 34 - lib/k8s/examples/resources/env.go | 31 - lib/k8s/examples/simple/env.go | 27 - .../examples/simple_toml/env_toml_config.go | 53 - lib/k8s/grafana/cl_insights.json | 3011 - lib/k8s/grafana/values.yml | 20 - .../httpchaos/chaosmeshorg/chaosmeshorg.go | 454 - .../chaosmeshorg/chaosmeshorg.init.go | 79 - .../httpchaos/chaosmeshorg/internal/types.go | 7 - .../chaosmeshorg/jsii/chaos-meshorg-0.0.0.tgz | Bin 24609 -> 0 bytes .../k8s/httpchaos/chaosmeshorg/jsii/jsii.go | 28 - .../k8s/httpchaos/chaosmeshorg/version | 1 - lib/k8s/imports/k8s/internal/types.go | 7 - .../k8s/iochaos/chaosmeshorg/chaosmeshorg.go | 484 - .../iochaos/chaosmeshorg/chaosmeshorg.init.go | 97 - .../iochaos/chaosmeshorg/internal/types.go | 7 - .../chaosmeshorg/jsii/chaos-meshorg-0.0.0.tgz | Bin 26345 -> 0 bytes .../k8s/iochaos/chaosmeshorg/jsii/jsii.go | 28 - .../imports/k8s/iochaos/chaosmeshorg/version | 1 - lib/k8s/imports/k8s/jsii/jsii.go | 28 - lib/k8s/imports/k8s/jsii/k8s-0.0.0.tgz | Bin 631564 -> 0 bytes lib/k8s/imports/k8s/k8s.go | 45510 ---------------- lib/k8s/imports/k8s/k8s.init.go | 4797 -- .../networkchaos/chaosmeshorg/chaosmeshorg.go | 567 - .../chaosmeshorg/chaosmeshorg.init.go | 129 - .../chaosmeshorg/internal/types.go | 7 - .../chaosmeshorg/jsii/chaos-meshorg-0.0.0.tgz | Bin 29221 -> 0 bytes .../networkchaos/chaosmeshorg/jsii/jsii.go | 28 - .../k8s/networkchaos/chaosmeshorg/version | 1 - .../k8s/podchaos/chaosmeshorg/chaosmeshorg.go | 404 - .../chaosmeshorg/chaosmeshorg.init.go | 68 - .../podchaos/chaosmeshorg/internal/types.go | 7 - .../chaosmeshorg/jsii/chaos-meshorg-0.0.0.tgz | Bin 20929 -> 0 bytes .../k8s/podchaos/chaosmeshorg/jsii/jsii.go | 28 - .../imports/k8s/podchaos/chaosmeshorg/version | 1 - .../podiochaos/chaosmeshorg/chaosmeshorg.go | 384 - .../chaosmeshorg/chaosmeshorg.init.go | 72 - .../podiochaos/chaosmeshorg/internal/types.go | 7 - .../chaosmeshorg/jsii/chaos-meshorg-0.0.0.tgz | Bin 19192 -> 0 bytes .../k8s/podiochaos/chaosmeshorg/jsii/jsii.go | 28 - .../k8s/podiochaos/chaosmeshorg/version | 1 - .../chaosmeshorg/chaosmeshorg.go | 396 - .../chaosmeshorg/chaosmeshorg.init.go | 76 - .../chaosmeshorg/internal/types.go | 7 - .../chaosmeshorg/jsii/chaos-meshorg-0.0.0.tgz | Bin 20404 -> 0 bytes .../podnetworkchaos/chaosmeshorg/jsii/jsii.go | 28 - .../k8s/podnetworkchaos/chaosmeshorg/version | 1 - .../stresschaos/chaosmeshorg/chaosmeshorg.go | 426 - .../chaosmeshorg/chaosmeshorg.init.go | 71 - .../chaosmeshorg/internal/types.go | 7 - .../chaosmeshorg/jsii/chaos-meshorg-0.0.0.tgz | Bin 22949 -> 0 bytes .../k8s/stresschaos/chaosmeshorg/jsii/jsii.go | 28 - .../k8s/stresschaos/chaosmeshorg/version | 1 - .../timechaos/chaosmeshorg/chaosmeshorg.go | 386 - .../chaosmeshorg/chaosmeshorg.init.go | 59 - .../timechaos/chaosmeshorg/internal/types.go | 7 - .../chaosmeshorg/jsii/chaos-meshorg-0.0.0.tgz | Bin 20411 -> 0 bytes .../k8s/timechaos/chaosmeshorg/jsii/jsii.go | 28 - .../k8s/timechaos/chaosmeshorg/version | 1 - lib/k8s/imports/k8s/version | 1 - lib/k8s/k3d.yaml | 19 - lib/k8s/pkg/alias/alias.go | 65 - lib/k8s/pkg/cdk8s/blockscout/blockscout.go | 241 - lib/k8s/pkg/cdk8s/goc/goc.go | 152 - lib/k8s/pkg/cdk8s/http_dummy/dummy.go | 167 - lib/k8s/pkg/common.go | 23 - lib/k8s/pkg/helm/chainlink/chainlink.go | 222 - lib/k8s/pkg/helm/ethereum/geth.go | 173 - lib/k8s/pkg/helm/foundry/foundry.go | 150 - lib/k8s/pkg/helm/foundry/foundry_test.go | 43 - lib/k8s/pkg/helm/grafana/grafana.go | 88 - lib/k8s/pkg/helm/influxdb/influxdb.go | 99 - lib/k8s/pkg/helm/kafka-rest/kafka-rest.go | 100 - lib/k8s/pkg/helm/kafka/kafka.go | 132 - lib/k8s/pkg/helm/mock-adapter/mock-adapter.go | 142 - .../pkg/helm/mockserver-cfg/mockserver-cfg.go | 74 - lib/k8s/pkg/helm/mockserver/mockserver.go | 147 - lib/k8s/pkg/helm/parrot/parrot.go | 141 - lib/k8s/pkg/helm/reorg/reorg.go | 229 - .../helm/schema-registry/schema-registry.go | 80 - lib/k8s/pkg/helm/sol/sol.go | 137 - lib/k8s/pkg/helm/starknet/starknet.go | 128 - lib/k8s/pkg/helm/wiremock/wiremock.go | 153 - lib/k8s/presets/presets.go | 237 - lib/k8s/scripts/buildBaseImage | 14 - lib/k8s/scripts/buildImageHelper | 40 - lib/k8s/scripts/buildTestImage | 24 - lib/k8s/scripts/buildTests | 24 - lib/k8s/scripts/entrypoint | 12 - lib/testreporters/log_scanner.go | 84 - lib/testreporters/reporter_model.go | 181 - lib/testreporters/reporter_model_test.go | 136 - lib/testreporters/slack_notification.go | 108 - lib/testsetups/migration.go | 73 - lib/utils/seth/seth.go | 32 - wasp/examples/go.mod | 1 + wasp/examples/simple_rps/main_test.go | 16 + 145 files changed, 47 insertions(+), 68117 deletions(-) delete mode 100644 lib/client/mockserver.go delete mode 100644 lib/client/mockserver_test.go delete mode 100644 lib/client/postgres.go delete mode 100644 lib/docker/test_env/mockserver.go delete mode 100644 lib/docker/test_env/mockserver_test.go delete mode 100644 lib/k8s/Dockerfile delete mode 100644 lib/k8s/Dockerfile.base delete mode 100644 lib/k8s/README.md delete mode 100644 lib/k8s/cdk8s.yaml delete mode 100644 lib/k8s/chaos/experiments.go delete mode 100644 lib/k8s/client/chaos.go delete mode 100644 lib/k8s/client/client.go delete mode 100644 lib/k8s/client/cmd.go delete mode 100644 lib/k8s/client/cmd_test.go delete mode 100644 lib/k8s/client/converter.go delete mode 100644 lib/k8s/client/forwarder.go rename lib/k8s/config/{overrides.go => config.go} (100%) delete mode 100644 lib/k8s/config/overrides_test.go delete mode 100644 lib/k8s/e2e/common/test_common.go delete mode 100644 lib/k8s/e2e/local-runner/envs_test.go delete mode 100644 lib/k8s/e2e/remote-runner/remote_runner_envs_test.go delete mode 100644 lib/k8s/environment/artifacts.go delete mode 100644 lib/k8s/environment/environment.go delete mode 100644 lib/k8s/environment/runner.go delete mode 100644 lib/k8s/examples/clones/clones.go delete mode 100644 lib/k8s/examples/concurrent/env_test.go delete mode 100644 lib/k8s/examples/coverage/Dockerfile delete mode 100644 lib/k8s/examples/coverage/Dockerfile.target delete mode 100755 lib/k8s/examples/coverage/entrypoint.sh delete mode 100644 lib/k8s/examples/coverage/env.go delete mode 100644 lib/k8s/examples/deployment_part/cmd/env.go delete mode 100644 lib/k8s/examples/deployment_part/sol.go delete mode 100644 lib/k8s/examples/deployment_part_cdk8s/blockscout.go delete mode 100644 lib/k8s/examples/deployment_part_cdk8s/cmd/env.go delete mode 100644 lib/k8s/examples/dump/env.go delete mode 100644 lib/k8s/examples/link/Dockerfile delete mode 100644 lib/k8s/examples/link/link_test.go delete mode 100644 lib/k8s/examples/modify_cdk8s/env.go delete mode 100644 lib/k8s/examples/modify_helm/env.go delete mode 100644 lib/k8s/examples/multistage/env.go delete mode 100644 lib/k8s/examples/multistage/someData.txt delete mode 100644 lib/k8s/examples/quick-debug/env.go delete mode 100644 lib/k8s/examples/remote-test-runner/env.go delete mode 100644 lib/k8s/examples/resources/env.go delete mode 100644 lib/k8s/examples/simple/env.go delete mode 100644 lib/k8s/examples/simple_toml/env_toml_config.go delete mode 100644 lib/k8s/grafana/cl_insights.json delete mode 100644 lib/k8s/grafana/values.yml delete mode 100644 lib/k8s/imports/k8s/httpchaos/chaosmeshorg/chaosmeshorg.go delete mode 100644 lib/k8s/imports/k8s/httpchaos/chaosmeshorg/chaosmeshorg.init.go delete mode 100644 lib/k8s/imports/k8s/httpchaos/chaosmeshorg/internal/types.go delete mode 100644 lib/k8s/imports/k8s/httpchaos/chaosmeshorg/jsii/chaos-meshorg-0.0.0.tgz delete mode 100644 lib/k8s/imports/k8s/httpchaos/chaosmeshorg/jsii/jsii.go delete mode 100644 lib/k8s/imports/k8s/httpchaos/chaosmeshorg/version delete mode 100644 lib/k8s/imports/k8s/internal/types.go delete mode 100644 lib/k8s/imports/k8s/iochaos/chaosmeshorg/chaosmeshorg.go delete mode 100644 lib/k8s/imports/k8s/iochaos/chaosmeshorg/chaosmeshorg.init.go delete mode 100644 lib/k8s/imports/k8s/iochaos/chaosmeshorg/internal/types.go delete mode 100644 lib/k8s/imports/k8s/iochaos/chaosmeshorg/jsii/chaos-meshorg-0.0.0.tgz delete mode 100644 lib/k8s/imports/k8s/iochaos/chaosmeshorg/jsii/jsii.go delete mode 100644 lib/k8s/imports/k8s/iochaos/chaosmeshorg/version delete mode 100644 lib/k8s/imports/k8s/jsii/jsii.go delete mode 100644 lib/k8s/imports/k8s/jsii/k8s-0.0.0.tgz delete mode 100644 lib/k8s/imports/k8s/k8s.go delete mode 100644 lib/k8s/imports/k8s/k8s.init.go delete mode 100644 lib/k8s/imports/k8s/networkchaos/chaosmeshorg/chaosmeshorg.go delete mode 100644 lib/k8s/imports/k8s/networkchaos/chaosmeshorg/chaosmeshorg.init.go delete mode 100644 lib/k8s/imports/k8s/networkchaos/chaosmeshorg/internal/types.go delete mode 100644 lib/k8s/imports/k8s/networkchaos/chaosmeshorg/jsii/chaos-meshorg-0.0.0.tgz delete mode 100644 lib/k8s/imports/k8s/networkchaos/chaosmeshorg/jsii/jsii.go delete mode 100644 lib/k8s/imports/k8s/networkchaos/chaosmeshorg/version delete mode 100644 lib/k8s/imports/k8s/podchaos/chaosmeshorg/chaosmeshorg.go delete mode 100644 lib/k8s/imports/k8s/podchaos/chaosmeshorg/chaosmeshorg.init.go delete mode 100644 lib/k8s/imports/k8s/podchaos/chaosmeshorg/internal/types.go delete mode 100644 lib/k8s/imports/k8s/podchaos/chaosmeshorg/jsii/chaos-meshorg-0.0.0.tgz delete mode 100644 lib/k8s/imports/k8s/podchaos/chaosmeshorg/jsii/jsii.go delete mode 100644 lib/k8s/imports/k8s/podchaos/chaosmeshorg/version delete mode 100644 lib/k8s/imports/k8s/podiochaos/chaosmeshorg/chaosmeshorg.go delete mode 100644 lib/k8s/imports/k8s/podiochaos/chaosmeshorg/chaosmeshorg.init.go delete mode 100644 lib/k8s/imports/k8s/podiochaos/chaosmeshorg/internal/types.go delete mode 100644 lib/k8s/imports/k8s/podiochaos/chaosmeshorg/jsii/chaos-meshorg-0.0.0.tgz delete mode 100644 lib/k8s/imports/k8s/podiochaos/chaosmeshorg/jsii/jsii.go delete mode 100644 lib/k8s/imports/k8s/podiochaos/chaosmeshorg/version delete mode 100644 lib/k8s/imports/k8s/podnetworkchaos/chaosmeshorg/chaosmeshorg.go delete mode 100644 lib/k8s/imports/k8s/podnetworkchaos/chaosmeshorg/chaosmeshorg.init.go delete mode 100644 lib/k8s/imports/k8s/podnetworkchaos/chaosmeshorg/internal/types.go delete mode 100644 lib/k8s/imports/k8s/podnetworkchaos/chaosmeshorg/jsii/chaos-meshorg-0.0.0.tgz delete mode 100644 lib/k8s/imports/k8s/podnetworkchaos/chaosmeshorg/jsii/jsii.go delete mode 100644 lib/k8s/imports/k8s/podnetworkchaos/chaosmeshorg/version delete mode 100644 lib/k8s/imports/k8s/stresschaos/chaosmeshorg/chaosmeshorg.go delete mode 100644 lib/k8s/imports/k8s/stresschaos/chaosmeshorg/chaosmeshorg.init.go delete mode 100644 lib/k8s/imports/k8s/stresschaos/chaosmeshorg/internal/types.go delete mode 100644 lib/k8s/imports/k8s/stresschaos/chaosmeshorg/jsii/chaos-meshorg-0.0.0.tgz delete mode 100644 lib/k8s/imports/k8s/stresschaos/chaosmeshorg/jsii/jsii.go delete mode 100644 lib/k8s/imports/k8s/stresschaos/chaosmeshorg/version delete mode 100644 lib/k8s/imports/k8s/timechaos/chaosmeshorg/chaosmeshorg.go delete mode 100644 lib/k8s/imports/k8s/timechaos/chaosmeshorg/chaosmeshorg.init.go delete mode 100644 lib/k8s/imports/k8s/timechaos/chaosmeshorg/internal/types.go delete mode 100644 lib/k8s/imports/k8s/timechaos/chaosmeshorg/jsii/chaos-meshorg-0.0.0.tgz delete mode 100644 lib/k8s/imports/k8s/timechaos/chaosmeshorg/jsii/jsii.go delete mode 100644 lib/k8s/imports/k8s/timechaos/chaosmeshorg/version delete mode 100644 lib/k8s/imports/k8s/version delete mode 100644 lib/k8s/k3d.yaml delete mode 100644 lib/k8s/pkg/alias/alias.go delete mode 100644 lib/k8s/pkg/cdk8s/blockscout/blockscout.go delete mode 100644 lib/k8s/pkg/cdk8s/goc/goc.go delete mode 100644 lib/k8s/pkg/cdk8s/http_dummy/dummy.go delete mode 100644 lib/k8s/pkg/common.go delete mode 100644 lib/k8s/pkg/helm/chainlink/chainlink.go delete mode 100644 lib/k8s/pkg/helm/ethereum/geth.go delete mode 100644 lib/k8s/pkg/helm/foundry/foundry.go delete mode 100644 lib/k8s/pkg/helm/foundry/foundry_test.go delete mode 100644 lib/k8s/pkg/helm/grafana/grafana.go delete mode 100644 lib/k8s/pkg/helm/influxdb/influxdb.go delete mode 100644 lib/k8s/pkg/helm/kafka-rest/kafka-rest.go delete mode 100644 lib/k8s/pkg/helm/kafka/kafka.go delete mode 100644 lib/k8s/pkg/helm/mock-adapter/mock-adapter.go delete mode 100644 lib/k8s/pkg/helm/mockserver-cfg/mockserver-cfg.go delete mode 100644 lib/k8s/pkg/helm/mockserver/mockserver.go delete mode 100644 lib/k8s/pkg/helm/parrot/parrot.go delete mode 100644 lib/k8s/pkg/helm/reorg/reorg.go delete mode 100644 lib/k8s/pkg/helm/schema-registry/schema-registry.go delete mode 100644 lib/k8s/pkg/helm/sol/sol.go delete mode 100644 lib/k8s/pkg/helm/starknet/starknet.go delete mode 100644 lib/k8s/pkg/helm/wiremock/wiremock.go delete mode 100644 lib/k8s/presets/presets.go delete mode 100755 lib/k8s/scripts/buildBaseImage delete mode 100755 lib/k8s/scripts/buildImageHelper delete mode 100755 lib/k8s/scripts/buildTestImage delete mode 100755 lib/k8s/scripts/buildTests delete mode 100755 lib/k8s/scripts/entrypoint delete mode 100644 lib/testreporters/log_scanner.go delete mode 100644 lib/testreporters/reporter_model.go delete mode 100644 lib/testreporters/reporter_model_test.go delete mode 100644 lib/testreporters/slack_notification.go delete mode 100644 lib/testsetups/migration.go diff --git a/framework/examples/myproject/fork_plus_offchain.toml b/framework/examples/myproject/fork_plus_offchain.toml index 4051ca2f1..b0214660d 100644 --- a/framework/examples/myproject/fork_plus_offchain.toml +++ b/framework/examples/myproject/fork_plus_offchain.toml @@ -1,8 +1,14 @@ [blockchain_src] chain_id = "1337" - docker_cmd_params = ["--steps-tracing", "--fork-block-number", "25335999", "--fork-url", "https://rpcs.cldev.sh/base/sepolia/archive", "--auto-impersonate"] -# docker_cmd_params = ["-b", "1", "--steps-tracing"] + port = "8545" + docker_cmd_params = ["-b", "1"] + type = "anvil" + +[blockchain_dst] + chain_id = "2337" + port = "8555" + docker_cmd_params = ["-b", "1"] type = "anvil" [contracts_src] diff --git a/framework/examples/myproject/fork_plus_offchain_test.go b/framework/examples/myproject/fork_plus_offchain_test.go index 103a5ea01..b14c01c04 100644 --- a/framework/examples/myproject/fork_plus_offchain_test.go +++ b/framework/examples/myproject/fork_plus_offchain_test.go @@ -19,6 +19,7 @@ import ( type CfgForkChainsOffChain struct { ContractsSrc *onchain.Input `toml:"contracts_src" validate:"required"` BlockchainSrc *blockchain.Input `toml:"blockchain_src" validate:"required"` + BlockchainDst *blockchain.Input `toml:"blockchain_dst" validate:"required"` // off-chain components NodeSets []*ns.Input `toml:"nodesets" validate:"required"` } @@ -31,6 +32,9 @@ func TestOffChainAndFork(t *testing.T) { bcSrc, err := blockchain.NewBlockchainNetwork(in.BlockchainSrc) require.NoError(t, err) + bcDst, err := blockchain.NewBlockchainNetwork(in.BlockchainDst) + require.NoError(t, err) + // create configs for 2 EVM networks srcNetworkCfg, err := clnode.NewNetworkCfg(&clnode.EVMNetworkConfig{ MinIncomingConfirmations: 1, @@ -38,12 +42,25 @@ func TestOffChainAndFork(t *testing.T) { ChainID: bcSrc.ChainID, EVMNodes: []*clnode.EVMNode{ { + Name: "one", SendOnly: false, Order: 100, }, }, }, bcSrc) - in.NodeSets[0].NodeSpecs[0].Node.TestConfigOverrides = srcNetworkCfg + dstNetworkCfg, err := clnode.NewNetworkCfg(&clnode.EVMNetworkConfig{ + MinIncomingConfirmations: 1, + MinContractPayment: "0.00001 link", + ChainID: bcDst.ChainID, + EVMNodes: []*clnode.EVMNode{ + { + Name: "two", + SendOnly: false, + Order: 100, + }, + }, + }, bcDst) + in.NodeSets[0].NodeSpecs[0].Node.TestConfigOverrides = srcNetworkCfg + dstNetworkCfg _, err = ns.NewSharedDBNodeSet(in.NodeSets[0], bcSrc) require.NoError(t, err) diff --git a/lib/blockchain/ethereum.go b/lib/blockchain/ethereum.go index 627b064a4..2c01bd5af 100644 --- a/lib/blockchain/ethereum.go +++ b/lib/blockchain/ethereum.go @@ -32,7 +32,6 @@ import ( "go.uber.org/atomic" "golang.org/x/sync/errgroup" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/environment" "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/conversions" ) @@ -1395,25 +1394,6 @@ func NewEVMClientFromNetwork(networkSettings EVMNetwork, logger zerolog.Logger) return wrappedClient, nil } -// NewEVMClient returns a multi-node EVM client connected to the specified network -// Note: This should mostly be deprecated in favor of ConnectEVMClient. This is really only used when needing to connect -// to simulated networks -func NewEVMClient(networkSettings EVMNetwork, env *environment.Environment, logger zerolog.Logger) (EVMClient, error) { - if env == nil { - return nil, fmt.Errorf("environment nil, use ConnectEVMClient or provide a non-nil environment") - } - - if networkSettings.Simulated { - if _, ok := env.URLs[networkSettings.Name]; !ok { - return nil, fmt.Errorf("network %s not found in environment", networkSettings.Name) - } - networkSettings.URLs = env.URLs[networkSettings.Name] - networkSettings.HTTPURLs = env.URLs[networkSettings.Name+"_http"] - } - - return ConnectEVMClient(networkSettings, logger) -} - // ConnectEVMClient returns a multi-node EVM client connected to a specified network, using only URLs. // Should mostly be used for inside K8s, non-simulated tests. func ConnectEVMClient(networkSettings EVMNetwork, logger zerolog.Logger) (EVMClient, error) { @@ -1485,54 +1465,6 @@ func ConnectEVMClient(networkSettings EVMNetwork, logger zerolog.Logger) (EVMCli return wrappedClient, nil } -// ConcurrentEVMClient returns a multi-node EVM client connected to a specified network -// It is used for concurrent interactions from different threads with the same network and from same owner -// account. This ensures that correct nonce value is fetched when an instance of EVMClient is initiated using this method. -// This is mainly useful for simulated networks as we don't use global nonce manager for them. -func ConcurrentEVMClient(networkSettings EVMNetwork, env *environment.Environment, existing EVMClient, logger zerolog.Logger) (EVMClient, error) { - // if not simulated use the NewEVMClient - if !networkSettings.Simulated { - return ConnectEVMClient(networkSettings, logger) - } - ecl := &EthereumMultinodeClient{} - if env != nil { - if _, ok := env.URLs[existing.GetNetworkConfig().Name]; !ok { - return nil, fmt.Errorf("network %s not found in environment", existing.GetNetworkConfig().Name) - } - networkSettings.URLs = env.URLs[existing.GetNetworkConfig().Name] - } - for idx, networkURL := range networkSettings.URLs { - networkSettings.URL = networkURL - ec, err := newEVMClient(networkSettings, logger) - if err != nil { - logger.Info(). - Err(err). - Str("URL Suffix", networkURL[len(networkURL)-6:]). - Msg("failed to create new EVM client") - continue - } - // a call to BalanceAt (can be any on chain call) to ensure the client is connected - _, err = ec.BalanceAt(context.Background(), ec.GetDefaultWallet().address) - if err == nil { - ec.SyncNonce(existing) - ec.SetID(idx) - ecl.Clients = append(ecl.Clients, ec) - break - } - } - if len(ecl.Clients) == 0 { - return nil, fmt.Errorf("failed to create new EVM client") - } - ecl.DefaultClient = ecl.Clients[0] - wrappedClient := wrapMultiClient(networkSettings, ecl) - ecl.SetWallets(existing.GetWallets()) - if err := ecl.SetDefaultWalletByAddress(existing.GetDefaultWallet().address); err != nil { - return nil, err - } - // no need to fund the account as it is already funded in the existing client - return wrappedClient, nil -} - // SetDefaultWalletByAddress sets default wallet by address if it exists, else returns error func (e *EthereumMultinodeClient) SetDefaultWalletByAddress(address common.Address) error { return e.DefaultClient.SetDefaultWalletByAddress(address) diff --git a/lib/client/mockserver.go b/lib/client/mockserver.go deleted file mode 100644 index 12d39df07..000000000 --- a/lib/client/mockserver.go +++ /dev/null @@ -1,315 +0,0 @@ -package client - -import ( - "crypto/tls" - "fmt" - "net/http" - "os" - "strings" - - "github.com/go-resty/resty/v2" - "github.com/rs/zerolog/log" - - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/environment" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/mockserver" -) - -// MockserverClient mockserver client -// -// Deprecated: Use Parrot instead -type MockserverClient struct { - APIClient *resty.Client - Config *MockserverConfig -} - -// MockserverConfig holds config information for MockserverClient -// -// Deprecated: Use Parrot instead -type MockserverConfig struct { - LocalURL string - ClusterURL string - Headers map[string]string -} - -// ConnectMockServer creates a connection to a deployed mockserver in the environment -// -// Deprecated: Use Parrot instead -func ConnectMockServer(e *environment.Environment) *MockserverClient { - c := NewMockserverClient(&MockserverConfig{ - LocalURL: e.URLs[mockserver.LocalURLsKey][0], - ClusterURL: e.URLs[mockserver.InternalURLsKey][0], - }) - return c -} - -// ConnectMockServerURL creates a connection to a mockserver at a given url, should only be used for inside K8s tests -// -// Deprecated: Use Parrot instead -func ConnectMockServerURL(url string) *MockserverClient { - c := NewMockserverClient(&MockserverConfig{ - LocalURL: url, - ClusterURL: url, - }) - return c -} - -// NewMockserverClient returns a mockserver client -// -// Deprecated: Use Parrot instead -func NewMockserverClient(cfg *MockserverConfig) *MockserverClient { - log.Debug().Str("Local URL", cfg.LocalURL).Str("Remote URL", cfg.ClusterURL).Msg("Connected to MockServer") - isDebug := os.Getenv("RESTY_DEBUG") == "true" - return &MockserverClient{ - Config: cfg, - APIClient: resty.New(). - SetBaseURL(cfg.LocalURL). - SetHeaders(cfg.Headers). - SetDebug(isDebug). - //nolint - SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true}), - } -} - -// PutExpectations sets the expectations (i.e. mocked responses) -func (em *MockserverClient) PutExpectations(body interface{}) error { - resp, err := em.APIClient.R().SetBody(body).Put("/expectation") - if resp.StatusCode() != http.StatusCreated { - err = fmt.Errorf("Unexpected Status Code. Expected %d; Got %d", http.StatusCreated, resp.StatusCode()) - } - return err -} - -// ClearExpectation clears expectations -func (em *MockserverClient) ClearExpectation(body interface{}) error { - resp, err := em.APIClient.R().SetBody(body).Put("/clear") - if resp.StatusCode() != http.StatusOK { - err = fmt.Errorf("Unexpected Status Code. Expected %d; Got %d", http.StatusOK, resp.StatusCode()) - } - return err -} - -// SetRandomValuePath sets a random int value for a path -func (em *MockserverClient) SetRandomValuePath(path string) error { - sanitizedPath := strings.ReplaceAll(path, "/", "_") - log.Debug().Str("ID", fmt.Sprintf("%s_mock_id", sanitizedPath)). - Str("Path", path). - Msg("Setting Random Value Mock Server Path") - initializer := HttpInitializerTemplate{ - Id: fmt.Sprintf("%s_mock_id", sanitizedPath), - Request: HttpRequest{Path: path}, - Response: HttpResponseTemplate{ - Template: "return { statusCode: 200, body: JSON.stringify({id: '', error: null, data: { result: Math.floor(Math.random() * (1000 - 900) + 900) } }) }", - TemplateType: "JAVASCRIPT", - }, - } - initializers := []HttpInitializerTemplate{initializer} - resp, err := em.APIClient.R().SetBody(&initializers).Put("/expectation") - if resp.StatusCode() != http.StatusCreated { - err = fmt.Errorf("status code expected %d got %d", http.StatusCreated, resp.StatusCode()) - } - return err -} - -// SetValuePath sets an int for a path -func (em *MockserverClient) SetValuePath(path string, v int) error { - if !strings.HasPrefix(path, "/") { - path = fmt.Sprintf("/%s", path) - } - sanitizedPath := strings.ReplaceAll(path, "/", "_") - log.Debug().Str("ID", fmt.Sprintf("%s_mock_id", sanitizedPath)). - Str("URL", em.APIClient.BaseURL). - Str("Path", path). - Int("Value", v). - Msg("Setting Mock Server Path") - initializer := HttpInitializer{ - Id: fmt.Sprintf("%s_mock_id", sanitizedPath), - Request: HttpRequest{Path: path}, - Response: HttpResponse{Body: AdapterResponse{ - Id: "", - Data: AdapterResult{Result: v}, - Error: nil, - }}, - } - initializers := []HttpInitializer{initializer} - resp, err := em.APIClient.R().SetBody(&initializers).Put("/expectation") - if resp.StatusCode() != http.StatusCreated { - err = fmt.Errorf("status code expected %d got %d, err: %s", http.StatusCreated, resp.StatusCode(), err) - } - return err -} - -// SetAnyValuePath sets any type of value for a path -func (em *MockserverClient) SetAnyValuePath(path string, v interface{}) error { - if !strings.HasPrefix(path, "/") { - path = fmt.Sprintf("/%s", path) - } - sanitizedPath := strings.ReplaceAll(path, "/", "_") - id := fmt.Sprintf("%s_mock_id", sanitizedPath) - log.Debug().Str("ID", id). - Str("Path", path). - Interface("Value", v). - Msg("Setting Mock Server Path") - initializer := HttpInitializer{ - Id: id, - Request: HttpRequest{Path: path}, - Response: HttpResponse{ - Body: AdapterResponse{ - Id: "", - Data: AdapterResult{ - Result: v, - }, - Error: nil, - }, - }, - } - initializers := []HttpInitializer{initializer} - resp, err := em.APIClient.R().SetBody(&initializers).Put("/expectation") - if resp.StatusCode() != http.StatusCreated { - err = fmt.Errorf("status code expected %d got %d", http.StatusCreated, resp.StatusCode()) - } - return err -} - -// SetAnyValueResponse configures a mock server to return a specified value for a given path. -// It ensures the path starts with a '/', sanitizes it, and logs the operation. -// This function is useful for testing and simulating API responses in a controlled environment. -func (em *MockserverClient) SetAnyValueResponse(path string, v interface{}) error { - if !strings.HasPrefix(path, "/") { - path = fmt.Sprintf("/%s", path) - } - sanitizedPath := strings.ReplaceAll(path, "/", "_") - id := fmt.Sprintf("%s_mock_id", sanitizedPath) - log.Debug().Str("ID", id). - Str("Path", path). - Interface("Value", v). - Msg("Setting Mock Server Path") - initializer := HttpInitializer{ - Id: id, - Request: HttpRequest{Path: path}, - Response: HttpResponse{ - Body: v, - }, - } - initializers := []HttpInitializer{initializer} - resp, err := em.APIClient.R().SetBody(&initializers).Put("/expectation") - if resp.StatusCode() != http.StatusCreated { - err = fmt.Errorf("status code expected %d got %d", http.StatusCreated, resp.StatusCode()) - } - return err -} - -// SetStringValuePath sets a string value for a path and returns it as a raw string -func (em *MockserverClient) SetStringValuePath(path string, stringValue string) error { - sanitizedPath := strings.ReplaceAll(path, "/", "_") - id := fmt.Sprintf("%s_mock_id", sanitizedPath) - log.Debug().Str("ID", id). - Str("Path", path). - Msg("Setting Mock Server String Path") - - initializer := HttpInitializer{ - Id: id, - Request: HttpRequest{Path: path}, - Response: HttpResponse{ - Body: stringValue, - }, - } - - initializers := []HttpInitializer{initializer} - resp, err := em.APIClient.R().SetBody(&initializers).Put("/expectation") - if resp.StatusCode() != http.StatusCreated { - err = fmt.Errorf("status code expected %d got %d", http.StatusCreated, resp.StatusCode()) - } - return err -} - -// LocalURL returns the local url of the mockserver -// -// Deprecated: Use Parrot instead -func (em *MockserverClient) LocalURL() string { - return em.Config.LocalURL -} - -// PathSelector represents the json object used to find expectations by path -// -// Deprecated: Use Parrot instead -type PathSelector struct { - Path string `json:"path"` -} - -// HttpRequest represents the httpRequest json object used in the mockserver initializer -// -// Deprecated: Use Parrot instead -type HttpRequest struct { - Path string `json:"path"` -} - -// HttpResponse represents the httpResponse json object used in the mockserver initializer -// -// Deprecated: Use Parrot instead -type HttpResponse struct { - Body interface{} `json:"body"` -} - -// HttpInitializer represents an element of the initializer array used in the mockserver initializer -// -// Deprecated: Use Parrot instead -type HttpInitializer struct { - Id string `json:"id"` - Request HttpRequest `json:"httpRequest"` - Response HttpResponse `json:"httpResponse"` -} - -// HttpResponse represents the httpResponse json object used in the mockserver initializer -// -// Deprecated: Use Parrot instead -type HttpResponseTemplate struct { - Template string `json:"template"` - TemplateType string `json:"templateType"` -} - -// HttpInitializer represents an element of the initializer array used in the mockserver initializer -// -// Deprecated: Use Parrot instead -type HttpInitializerTemplate struct { - Id string `json:"id"` - Request HttpRequest `json:"httpRequest"` - Response HttpResponseTemplate `json:"httpResponseTemplate"` -} - -// For OTPE - weiwatchers - -// NodeInfoJSON represents an element of the nodes array used to deliver configs to otpe -// -// Deprecated: Use Parrot instead -type NodeInfoJSON struct { - ID string `json:"id"` - NodeAddress []string `json:"nodeAddress"` -} - -// ContractInfoJSON represents an element of the contracts array used to deliver configs to otpe -// -// Deprecated: Use Parrot instead -type ContractInfoJSON struct { - ContractAddress string `json:"contractAddress"` - ContractVersion int `json:"contractVersion"` - Path string `json:"path"` - Status string `json:"status"` -} - -// For Adapter endpoints - -// AdapterResult represents an int result for an adapter -// -// Deprecated: Use Parrot instead -type AdapterResult struct { - Result interface{} `json:"result"` -} - -// AdapterResponse represents a response from an adapter -// -// Deprecated: Use Parrot instead -type AdapterResponse struct { - Id string `json:"id"` - Data AdapterResult `json:"data"` - Error interface{} `json:"error"` -} diff --git a/lib/client/mockserver_test.go b/lib/client/mockserver_test.go deleted file mode 100644 index 0caa000d6..000000000 --- a/lib/client/mockserver_test.go +++ /dev/null @@ -1,131 +0,0 @@ -package client_test - -import ( - "encoding/json" - "net/http" - "net/http/httptest" - "testing" - - "github.com/stretchr/testify/require" - - "github.com/smartcontractkit/chainlink-testing-framework/lib/client" -) - -func TestSetValuePath(t *testing.T) { - t.Parallel() - - server := mockedServer(func(rw http.ResponseWriter, req *http.Request) { - if req.Method == http.MethodPut { - switch req.URL.Path { - case "/expectation": - writeResponse(t, rw, http.StatusCreated, nil) - default: - require.Fail(t, "Path '%s' not supported", req.URL.Path) - } - } else { - require.Fail(t, "Method '%s' not supported", req.Method) - } - }) - defer server.Close() - - mockServerClient := newDefaultClient(server.URL) - err := mockServerClient.SetValuePath("variable", 5) - require.NoError(t, err) -} - -func TestSetStringValuePath(t *testing.T) { - t.Parallel() - - server := mockedServer(func(rw http.ResponseWriter, req *http.Request) { - if req.Method == http.MethodPut { - switch req.URL.Path { - case "/expectation": - writeResponse(t, rw, http.StatusCreated, nil) - default: - require.Fail(t, "Path '%s' not supported", req.URL.Path) - } - } else { - require.Fail(t, "Method '%s' not supported", req.Method) - } - }) - defer server.Close() - - mockServerClient := newDefaultClient(server.URL) - err := mockServerClient.SetStringValuePath("variable", "hello") - require.NoError(t, err) -} - -func TestPutExpectations(t *testing.T) { - t.Parallel() - - server := mockedServer(func(rw http.ResponseWriter, req *http.Request) { - if req.Method == http.MethodPut { - switch req.URL.Path { - case "/expectation": - writeResponse(t, rw, http.StatusCreated, nil) - default: - require.Fail(t, "Path '%s' not supported", req.URL.Path) - } - } else { - require.Fail(t, "Method '%s' not supported", req.Method) - } - }) - defer server.Close() - - mockServerClient := newDefaultClient(server.URL) - var nodesInfo []client.NodeInfoJSON - - nodesInitializer := client.HttpInitializer{ - Request: client.HttpRequest{Path: "/nodes.json"}, - Response: client.HttpResponse{Body: nodesInfo}, - } - initializers := []client.HttpInitializer{nodesInitializer} - - err := mockServerClient.PutExpectations(initializers) - require.NoError(t, err) -} - -func TestClearExpectations(t *testing.T) { - t.Parallel() - - server := mockedServer(func(rw http.ResponseWriter, req *http.Request) { - if req.Method == http.MethodPut { - switch req.URL.Path { - case "/clear": - writeResponse(t, rw, http.StatusOK, nil) - default: - require.Fail(t, "Path '%s' not supported", req.URL.Path) - } - } else { - require.Fail(t, "Method '%s' not supported", req.Method) - } - }) - defer server.Close() - - mockServerClient := newDefaultClient(server.URL) - err := mockServerClient.ClearExpectation(client.PathSelector{Path: "/nodes.json"}) - require.NoError(t, err) -} - -func newDefaultClient(url string) *client.MockserverClient { - ms := client.NewMockserverClient(&client.MockserverConfig{ - LocalURL: url, - ClusterURL: url, - }) - return ms -} - -func mockedServer(handlerFunc http.HandlerFunc) *httptest.Server { - return httptest.NewServer(handlerFunc) -} - -func writeResponse(t *testing.T, rw http.ResponseWriter, statusCode int, obj interface{}) { - rw.WriteHeader(statusCode) - if obj == nil { - return - } - b, err := json.Marshal(obj) - require.NoError(t, err) - _, err = rw.Write(b) - require.NoError(t, err) -} diff --git a/lib/client/postgres.go b/lib/client/postgres.go deleted file mode 100644 index c786bd4c2..000000000 --- a/lib/client/postgres.go +++ /dev/null @@ -1,73 +0,0 @@ -package client - -import ( - "fmt" - "strings" - - "github.com/jmoiron/sqlx" - // import for side effect of sql packages - _ "github.com/lib/pq" - "github.com/rs/zerolog/log" - - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/environment" -) - -// PostgresConnector sqlx postgres connector -type PostgresConnector struct { - *sqlx.DB - Cfg *PostgresConfig -} - -// PostgresConfig postgres config for connection string -type PostgresConfig struct { - Host string - Port string - User string - Password string - DBName string - SSLMode string -} - -// NewPostgresConnector creates new sqlx postgres connector -func NewPostgresConnector(cfg *PostgresConfig) (*PostgresConnector, error) { - var sslmode string - if cfg.SSLMode == "" { - sslmode = "sslmode=disable" - } else { - sslmode = fmt.Sprintf("sslmode=%s", cfg.SSLMode) - } - psqlInfo := fmt.Sprintf("host=%s port=%s user=%s "+ - "password=%s dbname=%s %s", - cfg.Host, cfg.Port, cfg.User, cfg.Password, cfg.DBName, sslmode) - log.Debug().Str("ConnectionString", psqlInfo).Msg("Connecting") - db, err := sqlx.Connect("postgres", psqlInfo) - if err != nil { - return nil, err - } - err = db.Ping() - if err != nil { - // nolint - db.Close() - return nil, err - } - log.Debug().Str("ConnectionString", psqlInfo).Msg("Connected") - return &PostgresConnector{DB: db, Cfg: cfg}, nil -} - -// ConnectDB establishes a connection to a PostgreSQL database using the provided environment settings. -// It returns a PostgresConnector instance or an error if the connection fails. -func ConnectDB(nodeNum int, e *environment.Environment) (*PostgresConnector, error) { - spl := strings.Split(e.URLs["chainlink_db"][nodeNum], ":") - port := spl[len(spl)-1] - db, err := NewPostgresConnector(&PostgresConfig{ - Host: "127.0.0.1", - Port: port, - User: "postgres", - Password: "postgres", - DBName: "chainlink", - }) - if err != nil { - return nil, err - } - return db, nil -} diff --git a/lib/docker/test_env/mockserver.go b/lib/docker/test_env/mockserver.go deleted file mode 100644 index d90ef539d..000000000 --- a/lib/docker/test_env/mockserver.go +++ /dev/null @@ -1,148 +0,0 @@ -package test_env - -import ( - "fmt" - "net/url" - "strings" - "testing" - "time" - - "github.com/google/uuid" - "github.com/rs/zerolog" - "github.com/rs/zerolog/log" - tc "github.com/testcontainers/testcontainers-go" - tcwait "github.com/testcontainers/testcontainers-go/wait" - - ctfClient "github.com/smartcontractkit/chainlink-testing-framework/lib/client" - "github.com/smartcontractkit/chainlink-testing-framework/lib/docker" - "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" - "github.com/smartcontractkit/chainlink-testing-framework/lib/mirror" - "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" -) - -const defaultMockServerImage = "mockserver/mockserver:5.15.0" - -// Deprecated: Use Parrot instead -type MockServer struct { - EnvComponent - //nolint:staticcheck // Ignore SA1019: MockserverClient is deprecated - Client *ctfClient.MockserverClient - Endpoint string - InternalEndpoint string - EAMockUrls []*url.URL - t *testing.T - l zerolog.Logger -} - -// NewMockServer creates a new instance of MockServer with specified networks and options. -// It initializes the server with a unique container name and a default startup timeout. -// This function is useful for testing decentralized applications in a controlled environment. -// -// Deprecated: Use Parrot instead -func NewMockServer(networks []string, opts ...EnvComponentOption) *MockServer { - ms := &MockServer{ - EnvComponent: EnvComponent{ - ContainerName: fmt.Sprintf("%s-%s", "mockserver", uuid.NewString()[0:8]), - Networks: networks, - StartupTimeout: 1 * time.Minute, - }, - l: log.Logger, - } - for _, opt := range opts { - opt(&ms.EnvComponent) - } - return ms -} - -// WithTestInstance configures the MockServer with a test logger and test context. -// It returns the updated MockServer instance for use in testing scenarios. -func (ms *MockServer) WithTestInstance(t *testing.T) *MockServer { - ms.l = logging.GetTestLogger(t) - ms.t = t - return ms -} - -// SetExternalAdapterMocks configures a specified number of mock external adapter endpoints. -// It generates unique paths for each adapter and stores their URLs for later use. -// This function is useful for testing scenarios that require multiple external adapter interactions. -func (ms *MockServer) SetExternalAdapterMocks(count int) error { - for i := 0; i < count; i++ { - path := fmt.Sprintf("/ea-%d", i) - err := ms.Client.SetRandomValuePath(path) - if err != nil { - return err - } - cName, err := ms.Container.Name(testcontext.Get(ms.t)) - if err != nil { - return err - } - cName = strings.Replace(cName, "/", "", -1) - eaUrl, err := url.Parse(fmt.Sprintf("http://%s:%s%s", - cName, "1080", path)) - if err != nil { - return err - } - ms.EAMockUrls = append(ms.EAMockUrls, eaUrl) - } - return nil -} - -// StartContainer initializes and starts a MockServer container. -// It sets up logging, retrieves the container request, and establishes endpoints for communication. -// This function is essential for testing environments that require a mock server instance. -func (ms *MockServer) StartContainer() error { - l := logging.GetTestContainersGoTestLogger(ms.t) - cr, err := ms.getContainerRequest() - if err != nil { - return err - } - c, err := docker.StartContainerWithRetry(ms.l, tc.GenericContainerRequest{ - ContainerRequest: cr, - Reuse: true, - Started: true, - Logger: l, - }) - if err != nil { - return fmt.Errorf("cannot start MockServer container: %w", err) - } - ms.Container = c - endpoint, err := GetEndpoint(testcontext.Get(ms.t), c, "http") - if err != nil { - return err - } - ms.l.Info().Any("endpoint", endpoint).Str("containerName", ms.ContainerName). - Msgf("Started MockServer container") - ms.Endpoint = endpoint - ms.InternalEndpoint = fmt.Sprintf("http://%s:%s", ms.ContainerName, "1080") - - //nolint:staticcheck // Ignore SA1019: client.NewMockserverClient is deprecated - client := ctfClient.NewMockserverClient(&ctfClient.MockserverConfig{ - LocalURL: endpoint, - ClusterURL: ms.InternalEndpoint, - }) - ms.Client = client - - return nil -} - -func (ms *MockServer) getContainerRequest() (tc.ContainerRequest, error) { - msImage := mirror.AddMirrorToImageIfSet(defaultMockServerImage) - - return tc.ContainerRequest{ - Name: ms.ContainerName, - Image: msImage, - ExposedPorts: []string{"1080/tcp"}, - Env: map[string]string{ - "SERVER_PORT": "1080", - }, - Networks: ms.Networks, - WaitingFor: tcwait.ForLog("INFO 1080 started on port: 1080"). - WithPollInterval(100 * time.Millisecond).WithStartupTimeout(ms.StartupTimeout), - LifecycleHooks: []tc.ContainerLifecycleHooks{ - { - PostStarts: ms.PostStartsHooks, - PostStops: ms.PostStopsHooks, - }, - }, - }, nil -} diff --git a/lib/docker/test_env/mockserver_test.go b/lib/docker/test_env/mockserver_test.go deleted file mode 100644 index 7aa22af48..000000000 --- a/lib/docker/test_env/mockserver_test.go +++ /dev/null @@ -1,48 +0,0 @@ -package test_env - -import ( - "bytes" - "fmt" - "net/http" - "testing" - "time" - - "github.com/stretchr/testify/require" - - "github.com/smartcontractkit/chainlink-testing-framework/lib/docker" - "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" -) - -func TestMockServerSetStringValue(t *testing.T) { - l := logging.GetTestLogger(t) - network, err := docker.CreateNetwork(l) - require.NoError(t, err) - - m := NewMockServer([]string{network.Name}). - WithTestInstance(t) - err = m.StartContainer() - require.NoError(t, err) - - expected := "bar" - path := "/foo" - err = m.Client.SetStringValuePath(path, expected) - require.NoError(t, err) - - //nolint:staticcheck // Ignore SA1019: client.NewMockserverClient is deprecated - url := fmt.Sprintf("%s%s", m.Client.LocalURL(), path) - client := &http.Client{ - Timeout: 10 * time.Second, - } - - resp, err := client.Get(url) - require.NoError(t, err) - defer resp.Body.Close() - require.Equal(t, http.StatusOK, resp.StatusCode) - - buf := new(bytes.Buffer) - _, err = buf.ReadFrom(resp.Body) - require.NoError(t, err) - - responseString := buf.String() - require.Equal(t, expected, responseString) -} diff --git a/lib/docker/test_env/parrot.go b/lib/docker/test_env/parrot.go index d761486ae..73181e40f 100644 --- a/lib/docker/test_env/parrot.go +++ b/lib/docker/test_env/parrot.go @@ -12,8 +12,6 @@ import ( tcwait "github.com/testcontainers/testcontainers-go/wait" "github.com/smartcontractkit/chainlink-testing-framework/lib/docker" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/environment" - helm_parrot "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/parrot" "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" "github.com/smartcontractkit/chainlink-testing-framework/lib/mirror" "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" @@ -79,13 +77,6 @@ func ConnectParrot(url string) *Parrot { } } -// ConnectParrotTestEnv connects to an existing Parrot server in a running test environment. -func ConnectParrotTestEnv(e *environment.Environment) *Parrot { - return &Parrot{ - Client: parrot.NewClient(e.URLs[helm_parrot.LocalURLsKey][0]), - } -} - // WithTestInstance configures the MockServer with a test logger and test context. // It returns the updated MockServer instance for use in testing scenarios. func (p *Parrot) WithTestInstance(t *testing.T) *Parrot { diff --git a/lib/go.mod b/lib/go.mod index 781701e8b..37ebd6372 100644 --- a/lib/go.mod +++ b/lib/go.mod @@ -8,11 +8,7 @@ require ( github.com/avast/retry-go v3.0.0+incompatible github.com/aws/aws-sdk-go-v2/config v1.28.0 github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.34.2 - github.com/aws/constructs-go/constructs/v10 v10.4.2 - github.com/aws/jsii-runtime-go v1.104.0 github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df - github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2 v2.7.5 - github.com/chaos-mesh/chaos-mesh/api v0.0.0-20240709130330-9f4feec7553f github.com/docker/docker v28.0.1+incompatible github.com/docker/go-connections v0.5.0 github.com/ethereum/go-ethereum v1.15.0 @@ -20,18 +16,15 @@ require ( github.com/google/go-github/v41 v41.0.0 github.com/google/uuid v1.6.0 github.com/imdario/mergo v0.3.16 - github.com/jmoiron/sqlx v1.4.0 github.com/joho/godotenv v1.5.1 github.com/kelseyhightower/envconfig v1.4.0 github.com/lib/pq v1.10.9 - github.com/onsi/gomega v1.34.2 github.com/otiai10/copy v1.14.0 github.com/pelletier/go-toml/v2 v2.2.3 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.20.5 github.com/prometheus/common v0.62.0 github.com/rs/zerolog v1.33.0 - github.com/slack-go/slack v0.15.0 github.com/smartcontractkit/chainlink-testing-framework/parrot v0.6.2 github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.10 github.com/spf13/cobra v1.8.1 @@ -39,16 +32,10 @@ require ( github.com/stretchr/testify v1.10.0 github.com/testcontainers/testcontainers-go v0.36.0 go.uber.org/atomic v1.11.0 - go.uber.org/zap v1.27.0 golang.org/x/net v0.34.0 golang.org/x/oauth2 v0.24.0 golang.org/x/sync v0.10.0 golang.org/x/text v0.21.0 - k8s.io/api v0.31.2 - k8s.io/apimachinery v0.31.2 - k8s.io/cli-runtime v0.31.2 - k8s.io/client-go v0.31.2 - k8s.io/kubectl v0.31.2 ) require ( @@ -57,16 +44,17 @@ require ( github.com/rs/xid v1.5.0 // indirect github.com/shirou/gopsutil/v4 v4.25.1 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect + go.opentelemetry.io/otel/sdk v1.28.0 // indirect + go.opentelemetry.io/proto/otlp v1.3.1 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect ) require ( github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect github.com/DataDog/zstd v1.5.2 // indirect - github.com/MakeNowJust/heredoc v1.0.0 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/VictoriaMetrics/fastcache v1.12.2 // indirect - github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect github.com/awalterschulze/gographviz v2.0.3+incompatible // indirect github.com/aws/aws-sdk-go-v2 v1.32.2 // indirect github.com/aws/aws-sdk-go-v2/credentials v1.17.41 // indirect @@ -81,12 +69,9 @@ require ( github.com/aws/aws-sdk-go-v2/service/sts v1.32.2 // indirect github.com/aws/smithy-go v1.22.0 // indirect github.com/benbjohnson/clock v1.3.5 // indirect - github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.17.0 // indirect - github.com/blang/semver/v4 v4.0.0 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/chai2010/gettext-go v1.0.2 // indirect github.com/consensys/bavard v0.1.22 // indirect github.com/consensys/gnark-crypto v0.14.0 // indirect github.com/containerd/log v0.1.0 // indirect @@ -99,119 +84,68 @@ require ( github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/distribution/reference v0.6.0 // indirect github.com/docker/go-units v0.5.0 // indirect - github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/ethereum/c-kzg-4844 v1.0.0 // indirect github.com/ethereum/go-verkle v0.2.2 // indirect - github.com/evanphx/json-patch v5.6.0+incompatible // indirect - github.com/evanphx/json-patch/v5 v5.9.0 // indirect - github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect - github.com/fatih/camelcase v1.0.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/fxamacker/cbor/v2 v2.7.0 // indirect - github.com/go-errors/errors v1.4.2 // 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-openapi/jsonpointer v0.20.0 // indirect - github.com/go-openapi/jsonreference v0.20.2 // indirect - github.com/go-openapi/swag v0.22.4 // indirect github.com/gofrs/flock v0.8.1 // 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.4 // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect - github.com/google/btree v1.1.2 // indirect - github.com/google/gnostic-models v0.6.8 // indirect - github.com/google/go-cmp v0.7.0 // indirect github.com/google/go-querystring v1.1.0 // indirect - github.com/google/gofuzz v1.2.0 // indirect - github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/gorilla/websocket v1.5.0 // indirect - github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect github.com/holiman/bloomfilter/v2 v2.0.3 // indirect github.com/holiman/uint256 v1.3.2 // 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/klauspost/compress v1.17.9 // indirect - github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect github.com/magiconair/properties v1.8.9 // indirect - github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.14 // indirect - github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect github.com/moby/patternmatcher v0.6.0 // indirect - github.com/moby/spdystream v0.4.0 // indirect github.com/moby/sys/sequential v0.5.0 // indirect github.com/moby/sys/user v0.1.0 // indirect github.com/moby/sys/userns v0.1.0 // 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/montanaflynn/stats v0.7.1 // indirect github.com/morikuni/aec v1.0.0 // indirect - github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.1 // indirect - github.com/peterbourgon/diskv v2.0.1+incompatible // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/procfs v0.15.1 // indirect github.com/rivo/uniseg v0.4.4 // indirect - github.com/robfig/cron/v3 v3.0.1 // indirect github.com/rs/cors v1.9.0 // indirect - github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/supranational/blst v0.3.13 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect - github.com/x448/float16 v0.8.4 // indirect - github.com/xlab/treeprint v1.2.0 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect go.opentelemetry.io/otel v1.35.0 // indirect go.opentelemetry.io/otel/metric v1.35.0 // indirect go.opentelemetry.io/otel/trace v1.35.0 // indirect - go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect - go.uber.org/multierr v1.11.0 // indirect go.uber.org/ratelimit v0.3.1 // indirect golang.org/x/crypto v0.32.0 // indirect golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect golang.org/x/sys v0.31.0 // indirect - golang.org/x/term v0.28.0 // indirect - golang.org/x/time v0.6.0 // indirect - gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect google.golang.org/grpc v1.65.0 google.golang.org/protobuf v1.36.1 // indirect - gopkg.in/evanphx/json-patch.v4 v4.12.0 // 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/apiextensions-apiserver v0.31.0 // indirect - k8s.io/component-base v0.31.2 // indirect - k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect - k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect rsc.io/tmplfunc v0.0.3 // indirect - sigs.k8s.io/controller-runtime v0.19.0 // indirect - sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect - sigs.k8s.io/kustomize/api v0.17.2 // indirect - sigs.k8s.io/kustomize/kyaml v0.17.1 // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect - sigs.k8s.io/yaml v1.4.0 // indirect ) retract ( diff --git a/lib/go.sum b/lib/go.sum index 0a3fad221..b969a825c 100644 --- a/lib/go.sum +++ b/lib/go.sum @@ -1,29 +1,19 @@ -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/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= 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/DataDog/zstd v1.5.2 h1:vUG4lAyuPCXO0TLbXvPv7EB7cNK1QV/luu55UHLrrn8= github.com/DataDog/zstd v1.5.2/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= -github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= -github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0= github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/VictoriaMetrics/fastcache v1.12.2 h1:N0y9ASrJ0F6h0QaC3o6uJb3NIZ9VKLjCM7NQbSmF7WI= github.com/VictoriaMetrics/fastcache v1.12.2/go.mod h1:AmC+Nzz1+3G2eCPapF6UcsnkThDcMsQicp4xDukwJYI= -github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= -github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/avast/retry-go v3.0.0+incompatible h1:4SOWQ7Qs+oroOTQOYnAHqelpCO0biHSxpiH9JdtuBj0= github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= github.com/awalterschulze/gographviz v2.0.3+incompatible h1:9sVEXJBJLwGX7EQVhLm2elIKCm7P2YHFC8v6096G09E= @@ -54,10 +44,6 @@ github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.2 h1:AhmO1fHINP9vFYUE0LHzCWg/ github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.2/go.mod h1:o8aQygT2+MVP0NaV6kbdE1YnnIM8RRVQzoeUH45GOdI= github.com/aws/aws-sdk-go-v2/service/sts v1.32.2 h1:CiS7i0+FUe+/YY1GvIBLLrR/XNGZ4CtM1Ll0XavNuVo= github.com/aws/aws-sdk-go-v2/service/sts v1.32.2/go.mod h1:HtaiBI8CjYoNVde8arShXb94UbQQi9L4EMr6D+xGBwo= -github.com/aws/constructs-go/constructs/v10 v10.4.2 h1:+hDLTsFGLJmKIn0Dg20vWpKBrVnFrEWYgTEY5UiTEG8= -github.com/aws/constructs-go/constructs/v10 v10.4.2/go.mod h1:cXsNCKDV+9eR9zYYfwy6QuE4uPFp6jsq6TtH1MwBx9w= -github.com/aws/jsii-runtime-go v1.104.0 h1:651Sh6J2FtatfnVzlOQ3/Ye1WWPAseZ6E/tSQxEKdSI= -github.com/aws/jsii-runtime-go v1.104.0/go.mod h1:7ZmQXxV0AAhhvv/GaHX4n6zbgA1tSRVdnQYAJbIhXHk= github.com/aws/smithy-go v1.22.0 h1:uunKnWlcoL3zO7q+gG2Pk53joueEOsnNB28QdMsmiMM= github.com/aws/smithy-go v1.22.0/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df h1:GSoSVRLoBaFpOOds6QyY1L8AX7uoY+Ln3BHc22W40X0= @@ -68,28 +54,16 @@ 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/bits-and-blooms/bitset v1.17.0 h1:1X2TS7aHz1ELcC0yU1y2stUs/0ig5oMU6STFZGrhvHI= github.com/bits-and-blooms/bitset v1.17.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= -github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= -github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= -github.com/bxcodec/faker v2.0.1+incompatible h1:P0KUpUw5w6WJXwrPfv35oc91i4d8nf40Nwln+M/+faA= -github.com/bxcodec/faker v2.0.1+incompatible/go.mod h1:BNzfpVdTwnFJ6GtfYTcQu6l6rHShT+veBxNCnjCx5XM= -github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2 v2.7.5 h1:rvc39Ol6z3MvaBzXkxFC6Nfsnixq/dRypushKDd7Nc0= -github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2 v2.7.5/go.mod h1:R/pdNYDYFQk+tuuOo7QES1kkv6OLmp5ze2XBZQIVffM= 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/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= 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/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk= -github.com/chai2010/gettext-go v1.0.2/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA= -github.com/chaos-mesh/chaos-mesh/api v0.0.0-20240709130330-9f4feec7553f h1:onZ3oc6l1Gz8pVpQ0c1U1Cb11kIMoDb3xtEy/iZbYZM= -github.com/chaos-mesh/chaos-mesh/api v0.0.0-20240709130330-9f4feec7553f/go.mod h1:x11iCbZV6hzzSQWMq610B6Wl5Lg1dhwqcVfeiWQQnQQ= 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/cockroachdb/errors v1.11.3 h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I= github.com/cockroachdb/errors v1.11.3/go.mod h1:m4UIW4CDjx+R5cybPsNrRbreomiFqt8o1h1wUVazSd8= github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce h1:giXvy4KSc/6g/esnpM7Geqxka4WSqI1SZc7sMJFd3y4= @@ -120,7 +94,6 @@ github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a h1:W8mUrRp6NOV github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a/go.mod h1:sTwzHBvIzm2RfVCGNEBZgRyjwK40bVoun3ZnGOCafNM= github.com/crate-crypto/go-kzg-4844 v1.1.0 h1:EN/u9k2TF6OWSHrCCDBBU6GLNMq88OspHHlMnHfoyU4= github.com/crate-crypto/go-kzg-4844 v1.1.0/go.mod h1:JolLjpSff1tCCJKaJx4psrlEdlXuJEC996PL3tTAFks= -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= @@ -143,24 +116,12 @@ 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/ebitengine/purego v0.8.2 h1:jPPGWs2sZ1UgOSgD2bClL0MJIqu58nOmIcBuXr62z1I= github.com/ebitengine/purego v0.8.2/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= -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/ethereum/c-kzg-4844 v1.0.0 h1:0X1LBXxaEtYD9xsyj9B9ctQEZIpnvVDeoBx8aHEwTNA= github.com/ethereum/c-kzg-4844 v1.0.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= github.com/ethereum/go-ethereum v1.15.0 h1:LLb2jCPsbJZcB4INw+E/MgzUX5wlR6SdwXcv09/1ME4= github.com/ethereum/go-ethereum v1.15.0/go.mod h1:4q+4t48P2C03sjqGvTXix5lEOplf5dz4CTosbjt5tGs= github.com/ethereum/go-verkle v0.2.2 h1:I2W0WjnrFUIzzVPwm8ykY+7pL2d4VhlsePn4j7cnFk8= github.com/ethereum/go-verkle v0.2.2/go.mod h1:M3b90YRnzqKyyzBEWJGqj8Qff4IDeXnzFw0P9bFw3uk= -github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= -github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg= -github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= -github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f h1:Wl78ApPPB2Wvf/TIe2xdyJxTlb6obmF18d8QdkxNDu4= -github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f/go.mod h1:OSYXu++VVOHnXeitef/D8n/6y4QV8uLHSFXX4NeXMGc= -github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8= -github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -168,42 +129,21 @@ github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4 github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= 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/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= -github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/go-chi/chi v1.5.5 h1:vOB/HbEMt9QqBqErz07QehcOKHaWFtuj87tTDVz2qXE= github.com/go-chi/chi v1.5.5/go.mod h1:C9JqLr3tIYjDOZpzn+BCuxY8z8vmca43EeMgyZt7irw= -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.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-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-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-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= -github.com/go-openapi/jsonpointer v0.20.0 h1:ESKJdU9ASRfaPNOPRx12IUyA1vn3R9GiE3KYD14BXdQ= -github.com/go-openapi/jsonpointer v0.20.0/go.mod h1:6PGzBjjIIumbLYysB73Klnms1mwnU4G3YHOECG3CedA= -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/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= -github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-resty/resty/v2 v2.16.3 h1:zacNT7lt4b8M/io2Ahj6yPypL7bqx9n1iprfQuodV+E= github.com/go-resty/resty/v2 v2.16.3/go.mod h1:hkJtXbA2iKHzJheXYvQ8snQES5ZLGKMwQ07xAwp/fiA= -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 v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -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/go-test/deep v1.0.4 h1:u2CU3YKy9I2pmu9pX0eq50wCgjfGIt539SqR7FbHiho= -github.com/go-test/deep v1.0.4/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= @@ -211,10 +151,6 @@ 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/v4 v4.5.1 h1:JdqV9zKUdtaa9gdPlywC3aeoEsR681PlKC+4F5gQgeo= github.com/golang-jwt/jwt/v4 v4.5.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -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/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.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -223,30 +159,18 @@ github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:x 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.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -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/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= -github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= -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.2/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.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/go-github/v41 v41.0.0 h1:HseJrM2JFf2vfiZJ8anY2hqBjdfY1Vlj/K27ueww4gg= @@ -257,19 +181,11 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/ 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-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5 h1:5iH8iuqE5apketRbSFBy+X1V0o+l+8NF1avt4HWl7cA= -github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5/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/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= 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/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA= -github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= 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/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= @@ -290,12 +206,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= -github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o= -github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY= 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/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -306,11 +218,8 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI 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.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/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= @@ -319,16 +228,10 @@ github.com/leanovate/gopter v0.2.11 h1:vRjThO1EKPb/1NsDXuDrzldR28RLkBflWYcU9CvzW github.com/leanovate/gopter v0.2.11/go.mod h1:aK3tzZP/C+p1m3SPRE4SYZFGP7jjkuSI4f7Xvpt0S9c= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -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/dedent v1.1.0 h1:VNzHMVCBNG1j0fh3OrsFRkVUwStdDArbgBWoPAffktY= -github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/magiconair/properties v1.8.9 h1:nWcCbLq1N2v/cpNsy5WvQ37Fb+YElfq20WJ/a8RkpQM= github.com/magiconair/properties v1.8.9/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= 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.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= @@ -338,10 +241,6 @@ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= -github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= -github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= -github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= 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/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= @@ -353,8 +252,6 @@ github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3N github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk= github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= -github.com/moby/spdystream v0.4.0 h1:Vy79D6mHeJJjiPdFEL2yku1kl0chZpJfZcPpb16BRl8= -github.com/moby/spdystream v0.4.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI= github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc= github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo= github.com/moby/sys/user v0.1.0 h1:WmZ93f5Ux6het5iituh9x2zAG7NFY9Aqi49jjE1PaQg= @@ -368,8 +265,6 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w 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/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE= github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= @@ -378,8 +273,6 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= -github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= @@ -387,17 +280,12 @@ github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6 github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= -github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/ginkgo/v2 v2.20.1 h1:YlVIbqct+ZmnEph770q9Q7NVAz4wwIiVNahee6JyUzo= -github.com/onsi/ginkgo/v2 v2.20.1/go.mod h1:lG9ey2Z29hR41WMVthyJBGUBcBhGOtoPF2VFMvBXFCI= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -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.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= @@ -408,8 +296,6 @@ github.com/otiai10/mint v1.5.1 h1:XaPLeE+9vGbuyEHem1JNk3bYc7KKqyI/na0/mLd/Kks= github.com/otiai10/mint v1.5.1/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM= github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M= github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= -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/pion/dtls/v2 v2.2.7 h1:cSUBsETxepsCSFSxC3mc/aDo14qQLMSL+O6IjG28yV8= github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= @@ -429,7 +315,6 @@ github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= 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.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io= @@ -439,8 +324,6 @@ github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoG 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/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= -github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/rs/cors v1.9.0 h1:l9HGsTsHJcvW14Nk7J9KFz8bzeAWXn3CG6bgt7LsrAE= @@ -449,18 +332,15 @@ github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= 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/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shirou/gopsutil/v4 v4.25.1 h1:QSWkTc+fu9LTAWfkZwZ6j8MSUk4A2LV7rbH0ZqmLjXs= github.com/shirou/gopsutil/v4 v4.25.1/go.mod h1:RoUCUpndaJFtT+2zsZzzmhvbfGoDCJ7nFXKJf8GqJbI= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/slack-go/slack v0.15.0 h1:LE2lj2y9vqqiOf+qIIy0GvEoxgF1N5yLGZffmEZykt0= -github.com/slack-go/slack v0.15.0/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw= github.com/smartcontractkit/chainlink-testing-framework/parrot v0.6.2 h1:cWUHB6QETyKbmh0B988f5AKIKb3aBDWugfrZ04jAUUY= github.com/smartcontractkit/chainlink-testing-framework/parrot v0.6.2/go.mod h1:Z4K5VJLjsfqIIaBcZ1Sfccxu0xsCxBjPa6zF+5gtQaM= github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.10 h1:Yf+n3T/fnUWcYyfe7bsygV4sWAkNo0QhN58APJFIKIc= @@ -470,20 +350,12 @@ github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3k 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.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.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -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.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= -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.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/supranational/blst v0.3.13 h1:AYeSxdOMacwu7FBmpfloBz5pbFXDmJL33RuwnKtmTjk= @@ -498,10 +370,6 @@ github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+F github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w= github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ= -github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= -github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= -github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= -github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -526,37 +394,21 @@ go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= 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.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/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -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/ratelimit v0.3.1 h1:K4qVE+byfv/B3tC+4nYWP7v/6SimcO7HzHekoMNBma0= go.uber.org/ratelimit v0.3.1/go.mod h1:6euWsTB6U/Nb3X++xEUXA8ciPJvr19Q/0h1+oDcJhRk= -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-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= -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/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-20180906233101-161cd47e91fd/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-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -573,13 +425,11 @@ golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAG golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE= golang.org/x/oauth2 v0.24.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.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= golang.org/x/sync v0.10.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-20180909124046-d0be0721c37e/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= @@ -611,7 +461,6 @@ golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= 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.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -624,37 +473,20 @@ golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= 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-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.29.0 h1:Xx0h3TtM9rzQpQuR4dKLrdglAmCEN5Oi+P74JdhdzXE= -golang.org/x/tools v0.29.0/go.mod h1:KMQVMRsVxU6nHCFXrBPhDB8XncLNLM0lIy/F14RP588= 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= golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -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/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/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -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/genproto v0.0.0-20230822172742-b8732ec3820d h1:VBu5YqKPv6XiJ199exd8Br+Aetz+o08F+PLMnwJQHAY= google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 h1:7whR9kGa5LUwFtpLm2ArCEejtnxlGeLbAyjFY8sGNFw= google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157/go.mod h1:99sLkeliLXfdj2J75X3Ho+rrVCaJze0uwN7zDDkjPVU= 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.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/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= @@ -662,10 +494,7 @@ google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ 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.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.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk= @@ -673,17 +502,12 @@ google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojt 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/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= -gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= -gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= 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.3.0/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= @@ -692,39 +516,5 @@ 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= -k8s.io/api v0.31.2 h1:3wLBbL5Uom/8Zy98GRPXpJ254nEFpl+hwndmk9RwmL0= -k8s.io/api v0.31.2/go.mod h1:bWmGvrGPssSK1ljmLzd3pwCQ9MgoTsRCuK35u6SygUk= -k8s.io/apiextensions-apiserver v0.31.0 h1:fZgCVhGwsclj3qCw1buVXCV6khjRzKC5eCFt24kyLSk= -k8s.io/apiextensions-apiserver v0.31.0/go.mod h1:b9aMDEYaEe5sdK+1T0KU78ApR/5ZVp4i56VacZYEHxk= -k8s.io/apimachinery v0.31.2 h1:i4vUt2hPK56W6mlT7Ry+AO8eEsyxMD1U44NR22CLTYw= -k8s.io/apimachinery v0.31.2/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= -k8s.io/cli-runtime v0.31.2 h1:7FQt4C4Xnqx8V1GJqymInK0FFsoC+fAZtbLqgXYVOLQ= -k8s.io/cli-runtime v0.31.2/go.mod h1:XROyicf+G7rQ6FQJMbeDV9jqxzkWXTYD6Uxd15noe0Q= -k8s.io/client-go v0.31.2 h1:Y2F4dxU5d3AQj+ybwSMqQnpZH9F30//1ObxOKlTI9yc= -k8s.io/client-go v0.31.2/go.mod h1:NPa74jSVR/+eez2dFsEIHNa+3o09vtNaWwWwb1qSxSs= -k8s.io/component-base v0.31.2 h1:Z1J1LIaC0AV+nzcPRFqfK09af6bZ4D1nAOpWsy9owlA= -k8s.io/component-base v0.31.2/go.mod h1:9PeyyFN/drHjtJZMCTkSpQJS3U9OXORnHQqMLDz0sUQ= -k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= -k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= -k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= -k8s.io/kubectl v0.31.2 h1:gTxbvRkMBwvTSAlobiTVqsH6S8Aa1aGyBcu5xYLsn8M= -k8s.io/kubectl v0.31.2/go.mod h1:EyASYVU6PY+032RrTh5ahtSOMgoDRIux9V1JLKtG5xM= -k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= -k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= -sigs.k8s.io/controller-runtime v0.19.0 h1:nWVM7aq+Il2ABxwiCizrVDSlmDcshi9llbaFbC0ji/Q= -sigs.k8s.io/controller-runtime v0.19.0/go.mod h1:iRmWllt8IlaLjvTTDLhRBXIEtkCK6hwVBJJsYS9Ajf4= -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.17.2 h1:E7/Fjk7V5fboiuijoZHgs4aHuexi5Y2loXlVOAVAG5g= -sigs.k8s.io/kustomize/api v0.17.2/go.mod h1:UWTz9Ct+MvoeQsHcJ5e+vziRRkwimm3HytpZgIYqye0= -sigs.k8s.io/kustomize/kyaml v0.17.1 h1:TnxYQxFXzbmNG6gOINgGWQt09GghzgTP6mIurOgrLCQ= -sigs.k8s.io/kustomize/kyaml v0.17.1/go.mod h1:9V0mCjIEYjlXuCdYsSXvyoy2BTsLESH7TlGV81S282U= -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/lib/k8s/Dockerfile b/lib/k8s/Dockerfile deleted file mode 100644 index 509871f13..000000000 --- a/lib/k8s/Dockerfile +++ /dev/null @@ -1,7 +0,0 @@ -ARG BASE_IMAGE -ARG IMAGE_VERSION=latest -FROM ${BASE_IMAGE}:${IMAGE_VERSION} -COPY lib/ testdir/ -WORKDIR /go/testdir -RUN ./k8s/scripts/buildTests -ENTRYPOINT ["./k8s/scripts/entrypoint"] diff --git a/lib/k8s/Dockerfile.base b/lib/k8s/Dockerfile.base deleted file mode 100644 index 170998d2b..000000000 --- a/lib/k8s/Dockerfile.base +++ /dev/null @@ -1,42 +0,0 @@ -# base test for all k8s test runs -FROM golang:1.24-bullseye - -ARG BASE_URL -ARG HELM_VERSION -ARG HOME -ARG KUBE_VERSION -ARG NODE_VERSION - -ENV GOOS="linux" -ENV BASE_URL="https://get.helm.sh" -ENV HELM_VERSION="3.10.3" -ENV KUBE_VERSION="v1.25.5" -ENV NODE_VERSION=18 - -RUN apt-get update && apt-get install -y ca-certificates wget curl git gnupg && \ - mkdir -p /etc/apt/keyrings && \ - curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg && \ - echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_VERSION.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list && \ - apt-get update && apt-get install -y nodejs && \ - curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl && \ - chmod +x ./kubectl && \ - mv ./kubectl /usr/local/bin && \ - case `uname -m` in \ - x86_64) ARCH=amd64; ;; \ - armv7l) ARCH=arm; ;; \ - aarch64) ARCH=arm64; ;; \ - ppc64le) ARCH=ppc64le; ;; \ - s390x) ARCH=s390x; ;; \ - *) echo "un-supported arch, exit ..."; exit 1; ;; \ - esac && \ - wget ${BASE_URL}/helm-v${HELM_VERSION}-linux-${ARCH}.tar.gz -O - | tar -xz && \ - mv linux-${ARCH}/helm /usr/bin/helm && \ - chmod +x /usr/bin/helm && \ - rm -rf linux-${ARCH} && \ - npm install -g yarn && \ - apt-get clean all && \ - helm repo add chainlink-qa https://raw.githubusercontent.com/smartcontractkit/qa-charts/gh-pages/ && \ - helm repo add bitnami https://charts.bitnami.com/bitnami && \ - helm repo update - -ENTRYPOINT ["sh"] diff --git a/lib/k8s/README.md b/lib/k8s/README.md deleted file mode 100644 index 1a25a5e59..000000000 --- a/lib/k8s/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# K8s Deployment (Deprecated) - -[![Documentation](https://img.shields.io/badge/Documentation-MDBook-blue?style=for-the-badge)](https://smartcontractkit.github.io/chainlink-testing-framework/lib/k8s/KUBERNETES.html) \ No newline at end of file diff --git a/lib/k8s/cdk8s.yaml b/lib/k8s/cdk8s.yaml deleted file mode 100644 index 36c1484f4..000000000 --- a/lib/k8s/cdk8s.yaml +++ /dev/null @@ -1,4 +0,0 @@ -language: go -app: go run . -imports: - - k8s@1.22.0 diff --git a/lib/k8s/chaos/experiments.go b/lib/k8s/chaos/experiments.go deleted file mode 100644 index 1e4db04f4..000000000 --- a/lib/k8s/chaos/experiments.go +++ /dev/null @@ -1,157 +0,0 @@ -package chaos - -import ( - "github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2" - - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/config" - networkChaos "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/imports/k8s/networkchaos/chaosmeshorg" - podChaos "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/imports/k8s/podchaos/chaosmeshorg" - "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/ptr" -) - -var ( - FOREVER = ptr.Ptr("999h") -) - -type ManifestFunc func(namespace string, props *Props) (cdk8s.App, string, string) - -type Props struct { - LabelsSelector *map[string]*string - ContainerNames *[]*string - DurationStr string - Delay string - FromLabels *map[string]*string - ToLabels *map[string]*string -} - -func blankManifest(namespace string) (cdk8s.App, cdk8s.Chart) { - app := cdk8s.NewApp(&cdk8s.AppProps{ - YamlOutputType: cdk8s.YamlOutputType_FILE_PER_APP, - }) - return app, cdk8s.NewChart(app, ptr.Ptr("root"), &cdk8s.ChartProps{ - Namespace: ptr.Ptr(namespace), - }) -} - -func NewKillPods(namespace string, props *Props) (cdk8s.App, string, string) { - config.JSIIGlobalMu.Lock() - defer config.JSIIGlobalMu.Unlock() - app, root := blankManifest(namespace) - c := podChaos.NewPodChaos(root, ptr.Ptr("experiment"), &podChaos.PodChaosProps{ - Spec: &podChaos.PodChaosSpec{ - Action: podChaos.PodChaosSpecAction_POD_KILL, - Mode: podChaos.PodChaosSpecMode_ALL, - Selector: &podChaos.PodChaosSpecSelector{ - LabelSelectors: props.LabelsSelector, - }, - Duration: FOREVER, - }, - }) - return app, *c.Name(), "podchaos" -} - -func NewFailPods(namespace string, props *Props) (cdk8s.App, string, string) { - config.JSIIGlobalMu.Lock() - defer config.JSIIGlobalMu.Unlock() - app, root := blankManifest(namespace) - c := podChaos.NewPodChaos(root, ptr.Ptr("experiment"), &podChaos.PodChaosProps{ - Spec: &podChaos.PodChaosSpec{ - Action: podChaos.PodChaosSpecAction_POD_FAILURE, - Mode: podChaos.PodChaosSpecMode_ALL, - Selector: &podChaos.PodChaosSpecSelector{ - LabelSelectors: props.LabelsSelector, - }, - Duration: ptr.Ptr(props.DurationStr), - }, - }) - return app, *c.Name(), "podchaos" -} - -func NewFailContainers(namespace string, props *Props) (cdk8s.App, string, string) { - config.JSIIGlobalMu.Lock() - defer config.JSIIGlobalMu.Unlock() - app, root := blankManifest(namespace) - c := podChaos.NewPodChaos(root, ptr.Ptr("experiment"), &podChaos.PodChaosProps{ - Spec: &podChaos.PodChaosSpec{ - Action: podChaos.PodChaosSpecAction_POD_KILL, - Mode: podChaos.PodChaosSpecMode_ALL, - Selector: &podChaos.PodChaosSpecSelector{ - LabelSelectors: props.LabelsSelector, - }, - ContainerNames: props.ContainerNames, - Duration: FOREVER, - }, - }) - return app, *c.Name(), "podchaos" -} - -func NewContainerKill(namespace string, props *Props) (cdk8s.App, string, string) { - config.JSIIGlobalMu.Lock() - defer config.JSIIGlobalMu.Unlock() - app, root := blankManifest(namespace) - c := podChaos.NewPodChaos(root, ptr.Ptr("experiment"), &podChaos.PodChaosProps{ - Spec: &podChaos.PodChaosSpec{ - Action: podChaos.PodChaosSpecAction_POD_KILL, - Mode: podChaos.PodChaosSpecMode_ALL, - Selector: &podChaos.PodChaosSpecSelector{ - LabelSelectors: props.LabelsSelector, - }, - Duration: FOREVER, - }, - }) - return app, *c.Name(), "podchaos" -} - -func NewNetworkPartition(namespace string, props *Props) (cdk8s.App, string, string) { - config.JSIIGlobalMu.Lock() - defer config.JSIIGlobalMu.Unlock() - app, root := blankManifest(namespace) - c := networkChaos.NewNetworkChaos(root, ptr.Ptr("experiment"), &networkChaos.NetworkChaosProps{ - Spec: &networkChaos.NetworkChaosSpec{ - Action: networkChaos.NetworkChaosSpecAction_PARTITION, - Mode: networkChaos.NetworkChaosSpecMode_ALL, - Selector: &networkChaos.NetworkChaosSpecSelector{ - LabelSelectors: props.FromLabels, - }, - Direction: networkChaos.NetworkChaosSpecDirection_BOTH, - Duration: ptr.Ptr(props.DurationStr), - ExternalTargets: nil, - Loss: &networkChaos.NetworkChaosSpecLoss{ - Loss: ptr.Ptr("100"), - }, - Target: &networkChaos.NetworkChaosSpecTarget{ - Mode: networkChaos.NetworkChaosSpecTargetMode_ALL, - Selector: &networkChaos.NetworkChaosSpecTargetSelector{ - LabelSelectors: props.ToLabels, - }, - }, - }, - }) - return app, *c.Name(), "networkchaos" -} - -func NewNetworkLatency(namespace string, props *Props) (cdk8s.App, string, string) { - app, root := blankManifest(namespace) - c := networkChaos.NewNetworkChaos(root, ptr.Ptr("experiment"), &networkChaos.NetworkChaosProps{ - Spec: &networkChaos.NetworkChaosSpec{ - Action: networkChaos.NetworkChaosSpecAction_DELAY, - Mode: networkChaos.NetworkChaosSpecMode_ALL, - Selector: &networkChaos.NetworkChaosSpecSelector{ - LabelSelectors: props.FromLabels, - }, - Direction: networkChaos.NetworkChaosSpecDirection_BOTH, - Duration: ptr.Ptr(props.DurationStr), - Delay: &networkChaos.NetworkChaosSpecDelay{ - Latency: ptr.Ptr(props.Delay), - Correlation: ptr.Ptr("100"), - }, - Target: &networkChaos.NetworkChaosSpecTarget{ - Mode: networkChaos.NetworkChaosSpecTargetMode_ALL, - Selector: &networkChaos.NetworkChaosSpecTargetSelector{ - LabelSelectors: props.ToLabels, - }, - }, - }, - }) - return app, *c.Name(), "networkchaos" -} diff --git a/lib/k8s/client/chaos.go b/lib/k8s/client/chaos.go deleted file mode 100644 index 2c54491ac..000000000 --- a/lib/k8s/client/chaos.go +++ /dev/null @@ -1,152 +0,0 @@ -package client - -import ( - "context" - "fmt" - "time" - - "github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2" - "github.com/chaos-mesh/chaos-mesh/api/v1alpha1" - "github.com/rs/zerolog/log" - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/util/json" - "k8s.io/apimachinery/pkg/util/wait" - - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/config" -) - -// Chaos is controller that manages Chaosmesh CRD instances to run experiments -type Chaos struct { - Client *K8sClient - ResourceByName map[string]string - Namespace string -} - -type ChaosState struct { - ChaosDetails v1alpha1.ChaosStatus `json:"status"` -} - -// NewChaos creates controller to run and stop chaos experiments -func NewChaos(client *K8sClient, namespace string) *Chaos { - return &Chaos{ - Client: client, - ResourceByName: make(map[string]string), - Namespace: namespace, - } -} - -// Run runs experiment and saves its ID -func (c *Chaos) Run(app cdk8s.App, id string, resource string) (string, error) { - log.Info().Msg("Applying chaos experiment") - config.JSIIGlobalMu.Lock() - manifest := *app.SynthYaml() - config.JSIIGlobalMu.Unlock() - log.Trace().Str("Raw", manifest).Msg("Manifest") - c.ResourceByName[id] = resource - if err := c.Client.Apply(context.Background(), manifest, c.Namespace, false); err != nil { - return id, err - } - if err := c.checkForPodsExistence(app); err != nil { - return id, err - } - err := c.waitForChaosStatus(id, v1alpha1.ConditionAllInjected, 5*time.Minute) - if err != nil { - return id, err - } - return id, nil -} - -func (c *Chaos) waitForChaosStatus(id string, condition v1alpha1.ChaosConditionType, timeout time.Duration) error { - var result ChaosState - log.Info().Msgf("waiting for chaos experiment state %s", condition) - if timeout < time.Minute { - log.Info().Msg("timeout is less than 1 minute, setting to 1 minute") - timeout = time.Minute - } - ctx, cancel := context.WithTimeout(context.Background(), timeout) - defer cancel() - return wait.PollUntilContextTimeout(ctx, 2*time.Second, timeout, true, func(ctx context.Context) (bool, error) { - data, err := c.Client.ClientSet. - RESTClient(). - Get(). - RequestURI(fmt.Sprintf("/apis/chaos-mesh.org/v1alpha1/namespaces/%s/%s/%s", c.Namespace, c.ResourceByName[id], id)). - Do(ctx). - Raw() - if err == nil { - err = json.Unmarshal(data, &result) - if err != nil { - return false, err - } - for _, c := range result.ChaosDetails.Conditions { - if c.Type == condition && c.Status == v1.ConditionTrue { - return true, err - } - } - } - return false, nil - }) -} - -func (c *Chaos) WaitForAllRecovered(id string, timeout time.Duration) error { - return c.waitForChaosStatus(id, v1alpha1.ConditionAllRecovered, timeout) -} - -// Stop removes a chaos experiment -func (c *Chaos) Stop(id string) error { - defer delete(c.ResourceByName, id) - return c.Client.DeleteResource(c.Namespace, c.ResourceByName[id], id) -} - -func (c *Chaos) checkForPodsExistence(app cdk8s.App) error { - charts := app.Charts() - var selectors []string - for _, chart := range *charts { - json := chart.ToJson() - for _, j := range *json { - m := j.(map[string]interface{}) - fmt.Println(m) - kind := m["kind"].(string) - if kind == "PodChaos" || kind == "NetworkChaos" { - selectors = append(selectors, getLabelSelectors(m["spec"].(map[string]interface{}))) - } - if kind == "NetworkChaos" { - target := m["spec"].(map[string]interface{})["target"].(map[string]interface{}) - selectors = append(selectors, getLabelSelectors(target)) - } - } - } - for _, selector := range selectors { - podList, err := c.Client.ListPods(c.Namespace, selector) - if err != nil { - return err - } - if podList == nil || len(podList.Items) == 0 { - return fmt.Errorf("no pods found for selector %s", selector) - } - log.Info(). - Int("podsCount", len(podList.Items)). - Str("selector", selector). - Msgf("found pods for chaos experiment") - } - return nil -} - -func getLabelSelectors(spec map[string]interface{}) string { - if spec == nil { - return "" - } - s := spec["selector"].(map[string]interface{}) - if s == nil { - return "" - } - m := s["labelSelectors"].(map[string]interface{}) - selector := "" - for key, value := range m { - if selector == "" { - selector = fmt.Sprintf("%s=%s", key, value) - } else { - selector = fmt.Sprintf("%s, %s=%s", selector, key, value) - } - } - return selector -} diff --git a/lib/k8s/client/client.go b/lib/k8s/client/client.go deleted file mode 100644 index 6f1543dac..000000000 --- a/lib/k8s/client/client.go +++ /dev/null @@ -1,572 +0,0 @@ -package client - -import ( - "bytes" - "context" - "fmt" - "os" - "regexp" - "sort" - "strconv" - "strings" - "time" - - "github.com/google/uuid" - "github.com/rs/zerolog/log" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/runtime/serializer" - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/wait" - "k8s.io/cli-runtime/pkg/genericclioptions" - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/tools/remotecommand" - "k8s.io/kubectl/pkg/cmd/cp" - - v1 "k8s.io/api/core/v1" - metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/kubernetes" - "k8s.io/client-go/rest" - "k8s.io/client-go/tools/clientcmd" - cmdutil "k8s.io/kubectl/pkg/cmd/util" -) - -const ( - TempDebugManifest = "tmp-manifest-%s.yaml" - K8sStatePollInterval = 10 * time.Second - JobFinalizedTimeout = 2 * time.Minute - AppLabel = "app" -) - -// K8sClient high level k8s client -type K8sClient struct { - ClientSet *kubernetes.Clientset - RESTConfig *rest.Config -} - -// GetLocalK8sDeps get local k8s context config -func GetLocalK8sDeps() (*kubernetes.Clientset, *rest.Config, error) { - loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() - kubeConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, &clientcmd.ConfigOverrides{}) - k8sConfig, err := kubeConfig.ClientConfig() - if err != nil { - return nil, nil, err - } - k8sClient, err := kubernetes.NewForConfig(k8sConfig) - if err != nil { - return nil, nil, err - } - return k8sClient, k8sConfig, nil -} - -// NewK8sClient creates a new k8s client with a REST config -func NewK8sClient() (*K8sClient, error) { - cs, cfg, err := GetLocalK8sDeps() - if err != nil { - return nil, err - } - return &K8sClient{ - ClientSet: cs, - RESTConfig: cfg, - }, nil -} - -// ListPods lists pods for a namespace and selector -func (m *K8sClient) ListPods(namespace, selector string) (*v1.PodList, error) { - pods, err := m.ClientSet.CoreV1().Pods(namespace).List(context.Background(), metaV1.ListOptions{LabelSelector: selector}) - sort.Slice(pods.Items, func(i, j int) bool { - return pods.Items[i].CreationTimestamp.Before(pods.Items[j].CreationTimestamp.DeepCopy()) - }) - return pods.DeepCopy(), err -} - -// ListPods lists services for a namespace and selector -func (m *K8sClient) ListServices(namespace, selector string) (*v1.ServiceList, error) { - services, err := m.ClientSet.CoreV1().Services(namespace).List(context.Background(), metaV1.ListOptions{LabelSelector: selector}) - return services.DeepCopy(), err -} - -// ListNamespaces lists k8s namespaces -func (m *K8sClient) ListNamespaces(selector string) (*v1.NamespaceList, error) { - return m.ClientSet.CoreV1().Namespaces().List(context.Background(), metaV1.ListOptions{LabelSelector: selector}) -} - -// AddLabel adds a new label to a group of pods defined by selector -func (m *K8sClient) AddLabel(namespace string, selector string, label string) error { - podList, err := m.ListPods(namespace, selector) - if err != nil { - return err - } - l := strings.Split(label, "=") - if len(l) != 2 { - return fmt.Errorf("labels must be in format key=value") - } - for _, pod := range podList.Items { - labelPatch := fmt.Sprintf(`[{"op":"add","path":"/metadata/labels/%s","value":"%s" }]`, l[0], l[1]) - _, err := m.ClientSet.CoreV1().Pods(namespace).Patch( - context.Background(), - pod.GetName(), - types.JSONPatchType, - []byte(labelPatch), - metaV1.PatchOptions{}, - ) - if err != nil { - return fmt.Errorf("failed to update labels %s for pod %s err: %w", labelPatch, pod.Name, err) - } - } - log.Debug().Str("Selector", selector).Str("Label", label).Msg("Updated label") - return nil -} - -func (m *K8sClient) LabelChaosGroup(namespace string, labelPrefix string, startInstance int, endInstance int, group string) error { - for i := startInstance; i <= endInstance; i++ { - err := m.AddLabel(namespace, fmt.Sprintf("%s%d", labelPrefix, i), fmt.Sprintf("%s=1", group)) - if err != nil { - return err - } - } - return nil -} - -func (m *K8sClient) LabelChaosGroupByLabels(namespace string, labels map[string]string, group string) error { - labelSelector := "" - for key, value := range labels { - if labelSelector == "" { - labelSelector = fmt.Sprintf("%s=%s", key, value) - } else { - labelSelector = fmt.Sprintf("%s, %s=%s", labelSelector, key, value) - } - } - podList, err := m.ListPods(namespace, labelSelector) - if err != nil { - return err - } - for _, pod := range podList.Items { - err = m.AddPodLabel(namespace, pod, group, "1") - if err != nil { - return err - } - } - return nil -} - -// AddPodsLabels adds map of labels to all pods in list -func (m *K8sClient) AddPodsLabels(namespace string, podList *v1.PodList, labels map[string]string) error { - for _, pod := range podList.Items { - for k, v := range labels { - err := m.AddPodLabel(namespace, pod, k, v) - if err != nil { - return err - } - } - } - return nil -} - -// AddPodsAnnotations adds map of annotations to all pods in list -func (m *K8sClient) AddPodsAnnotations(namespace string, podList *v1.PodList, annotations map[string]string) error { - // when applying annotations the key doesn't like `/` characters here but everywhere else it does - // replacing it here with ~1 - fixedAnnotations := make(map[string]string) - for k, v := range annotations { - fixedAnnotations[strings.ReplaceAll(k, "/", "~1")] = v - } - for _, pod := range podList.Items { - for k, v := range fixedAnnotations { - err := m.AddPodAnnotation(namespace, pod, k, v) - if err != nil { - return err - } - } - } - return nil -} - -// UniqueLabels gets all unique application labels -func (m *K8sClient) UniqueLabels(namespace string, selector string) ([]string, error) { - uniqueLabels := make([]string, 0) - isUnique := make(map[string]bool) - podList, err := m.ListPods(namespace, selector) - if err != nil { - return nil, err - } - for _, p := range podList.Items { - appLabel := p.Labels[AppLabel] - if _, ok := isUnique[appLabel]; !ok { - uniqueLabels = append(uniqueLabels, appLabel) - } - } - log.Info(). - Interface("Apps", uniqueLabels). - Int("Count", len(uniqueLabels)). - Msg("Apps found") - return uniqueLabels, nil -} - -// AddPodLabel adds a label to a pod -func (m *K8sClient) AddPodLabel(namespace string, pod v1.Pod, key, value string) error { - labelPatch := fmt.Sprintf(`[{"op":"add","path":"/metadata/labels/%s","value":"%s" }]`, key, value) - _, err := m.ClientSet.CoreV1().Pods(namespace).Patch( - context.Background(), pod.GetName(), types.JSONPatchType, []byte(labelPatch), metaV1.PatchOptions{}) - if err != nil { - return err - } - return nil -} - -// AddPodAnnotation adds an annotation to a pod -func (m *K8sClient) AddPodAnnotation(namespace string, pod v1.Pod, key, value string) error { - labelPatch := fmt.Sprintf(`[{"op":"add","path":"/metadata/annotations/%s","value":"%s" }]`, key, value) - _, err := m.ClientSet.CoreV1().Pods(namespace).Patch( - context.Background(), pod.GetName(), types.JSONPatchType, []byte(labelPatch), metaV1.PatchOptions{}) - if err != nil { - return err - } - return nil -} - -// EnumerateInstances enumerate pods with instance label -func (m *K8sClient) EnumerateInstances(namespace string, selector string) error { - podList, err := m.ListPods(namespace, selector) - if err != nil { - return err - } - - for id, pod := range podList.Items { - // skip if already labeled with instance - existingLabels := pod.Labels - _, exists := existingLabels["instance"] - if exists { - continue - } - if err := m.AddPodLabel(namespace, pod, "instance", strconv.Itoa(id)); err != nil { - return err - } - } - return nil -} - -// waitForPodsExist waits for all the expected number of pods to exist -func (m *K8sClient) waitForPodsExist(ns string, expectedPodCount int) error { - log.Debug().Int("ExpectedCount", expectedPodCount).Msg("Waiting for pods to exist") - var exitErr error - timeout := 15 * time.Minute - ctx, cancel := context.WithTimeout(context.Background(), timeout) - defer cancel() - if err := wait.PollUntilContextTimeout(ctx, 2*time.Second, timeout, true, func(ctx context.Context) (bool, error) { - // nolint:contextcheck - apps, err2 := m.UniqueLabels(ns, AppLabel) - if err2 != nil { - exitErr = err2 - return false, nil - } - if len(apps) >= expectedPodCount { - exitErr = nil - return true, nil - } - return false, nil - }); err != nil { - return err - } - - return exitErr -} - -// WaitPodsReady waits until all pods are ready -func (m *K8sClient) WaitPodsReady(ns string, rcd *ReadyCheckData, expectedPodCount int) error { - // Wait for pods to exist - err := m.waitForPodsExist(ns, expectedPodCount) - if err != nil { - return err - } - - log.Info().Msg("Waiting for pods to be ready") - ticker := time.NewTicker(K8sStatePollInterval) - defer ticker.Stop() - timeout := time.NewTimer(rcd.Timeout) - readyCount := 0 - defer timeout.Stop() - for { - select { - case <-timeout.C: - return fmt.Errorf("waitcontainersready, no pods in '%s' with selector '%s' after timeout '%s'", - ns, rcd.ReadinessProbeCheckSelector, rcd.Timeout) - case <-ticker.C: - podList, err := m.ListPods(ns, rcd.ReadinessProbeCheckSelector) - if err != nil { - return err - } - if len(podList.Items) == 0 && expectedPodCount > 0 { - log.Debug(). - Str("Namespace", ns). - Str("Selector", rcd.ReadinessProbeCheckSelector). - Msg("No pods found with selector") - continue - } - log.Debug().Interface("Pods", podNames(podList)).Msg("Waiting for pods readiness probes") - allReady := true - for _, pod := range podList.Items { - if pod.Status.Phase == "Succeeded" { - log.Debug().Str("Pod", pod.Name).Msg("Pod is in Succeeded state") - continue - } else if pod.Status.Phase != v1.PodRunning { - log.Debug().Str("Pod", pod.Name).Str("Phase", string(pod.Status.Phase)).Msg("Pod is not running") - allReady = false - break - } - for _, c := range pod.Status.Conditions { - if c.Type == v1.ContainersReady && c.Status != "True" { - log.Debug().Str("Text", c.Message).Msg("Pod condition message") - allReady = false - } - } - } - - if allReady { - readyCount++ - // wait for it to be ready 3 times since there is no good way to know if an old pod - // was present but not yet decommisiond during a rollout - // usually there is just a very small blip that we can run into this and this will - // prevent that from happening - if readyCount == 3 { - return nil - } - } - } - } -} - -// NamespaceExists check if namespace exists -func (m *K8sClient) NamespaceExists(namespace string) bool { - if _, err := m.ClientSet.CoreV1().Namespaces().Get(context.Background(), namespace, metaV1.GetOptions{}); err != nil { - return false - } - return true -} - -// RemoveNamespace removes namespace -func (m *K8sClient) RemoveNamespace(namespace string) error { - log.Info().Str("Namespace", namespace).Msg("Removing namespace") - return m.ClientSet.CoreV1().Namespaces().Delete(context.Background(), namespace, metaV1.DeleteOptions{}) -} - -// CopyFromPod copies src from a particular namespace:pod:container to local. -func (m *K8sClient) CopyFromPod(ctx context.Context, namespace, podName, containername, srcPath, destPath string) error { - scmd := fmt.Sprintf("kubectl cp %s/%s:%s -c %s %s", namespace, podName, srcPath, containername, destPath) - log.Info().Str("Command", scmd).Msg("Waiting to finish copying") - return ExecCmdWithContext(ctx, scmd) -} - -// RolloutStatefulSets applies "rollout statefulset" to all existing statefulsets in that namespace -func (m *K8sClient) RolloutStatefulSets(ctx context.Context, namespace string) error { - stsClient := m.ClientSet.AppsV1().StatefulSets(namespace) - sts, err := stsClient.List(ctx, metaV1.ListOptions{}) - if err != nil { - return err - } - for _, s := range sts.Items { - cmd := fmt.Sprintf("kubectl rollout restart statefulset %s --namespace %s", s.Name, namespace) - log.Info().Str("Command", cmd).Msg("Applying StatefulSet rollout") - if err := ExecCmdWithContext(ctx, cmd); err != nil { - return err - } - } - // wait for the statefulsets to be ready in a separate loop otherwise this can take a long time - for _, s := range sts.Items { - // wait for the rollout to be complete - scmd := fmt.Sprintf("kubectl rollout status statefulset %s --namespace %s", s.Name, namespace) - log.Info().Str("Command", scmd).Msg("Waiting for StatefulSet rollout to finish") - if err := ExecCmdWithContext(ctx, scmd); err != nil { - return err - } - } - return nil -} - -// RolloutRestartBySelector rollouts and restarts object by selector -func (m *K8sClient) RolloutRestartBySelector(ctx context.Context, namespace, resource, selector string) error { - cmd := fmt.Sprintf("kubectl --namespace %s rollout restart -l %s %s", namespace, selector, resource) - log.Info().Str("Command", cmd).Msg("rollout restart by selector") - if err := ExecCmdWithContext(ctx, cmd); err != nil { - return err - } - // wait for the rollout to be complete - waitCmd := fmt.Sprintf("kubectl --namespace %s rollout status -l %s %s", namespace, selector, resource) - log.Info().Str("Command", waitCmd).Msg("Waiting for StatefulSet rollout to finish") - return ExecCmdWithContext(ctx, waitCmd) -} - -// ReadyCheckData data to check if selected pods are running and all containers are ready ( readiness check ) are ready -type ReadyCheckData struct { - ReadinessProbeCheckSelector string - Timeout time.Duration -} - -// WaitForJob wait for job execution, follow logs and returns an error if job failed -func (m *K8sClient) WaitForJob(namespaceName string, jobName string, fundReturnStatus func(string)) error { - cmd := fmt.Sprintf("kubectl --namespace %s logs --follow job/%s", namespaceName, jobName) - log.Info().Str("Job", jobName).Str("cmd", cmd).Msg("Waiting for job to complete") - ctx := context.Background() - if err := ExecCmdWithOptions(ctx, cmd, fundReturnStatus); err != nil { - return err - } - var exitErr error - ctx, cancel := context.WithTimeout(ctx, JobFinalizedTimeout) - defer cancel() - if err := wait.PollUntilContextTimeout(ctx, K8sStatePollInterval, JobFinalizedTimeout, true, func(ctx context.Context) (bool, error) { - job, err := m.ClientSet.BatchV1().Jobs(namespaceName).Get(ctx, jobName, metaV1.GetOptions{}) - if err != nil { - exitErr = err - } - if int(job.Status.Failed) > 0 { - exitErr = fmt.Errorf("job failed") - return true, nil - } - if int(job.Status.Succeeded) > 0 { - exitErr = nil - return true, nil - } - return false, nil - }); err != nil { - return err - } - return exitErr -} - -func (m *K8sClient) WaitForDeploymentsAvailable(ctx context.Context, namespace string) error { - deployments, err := m.ClientSet.AppsV1().Deployments(namespace).List(ctx, metaV1.ListOptions{}) - if err != nil { - return err - } - log.Debug().Int("Number", len(deployments.Items)).Msg("Deployments found") - for _, d := range deployments.Items { - log.Debug().Str("status", d.Status.String()).Msg("Deployment info") - waitCmd := fmt.Sprintf("kubectl rollout status -n %s deployment/%s", namespace, d.Name) - log.Debug().Str("cmd", waitCmd).Msg("wait for deployment to be available") - if err := ExecCmdWithContext(ctx, waitCmd); err != nil { - return err - } - } - return nil -} - -// Apply applying a manifest to a currently connected k8s context -func (m *K8sClient) Apply(ctx context.Context, manifest, namespace string, waitForDeployment bool) error { - manifestFile := fmt.Sprintf(TempDebugManifest, uuid.NewString()) - log.Info().Str("File", manifestFile).Msg("Applying manifest") - if err := os.WriteFile(manifestFile, []byte(manifest), os.ModePerm); err != nil { - return err - } - cmd := fmt.Sprintf("kubectl apply -f %s", manifestFile) - log.Debug().Str("cmd", cmd).Msg("Apply command") - if err := ExecCmdWithContext(ctx, cmd); err != nil { - return err - } - if waitForDeployment { - return m.WaitForDeploymentsAvailable(ctx, namespace) - } - return nil -} - -// DeleteResource deletes resource -func (m *K8sClient) DeleteResource(namespace string, resource string, instance string) error { - return ExecCmd(fmt.Sprintf("kubectl delete %s %s --namespace %s", resource, instance, namespace)) -} - -// Create creating a manifest to a currently connected k8s context -func (m *K8sClient) Create(manifest string) error { - manifestFile := fmt.Sprintf(TempDebugManifest, uuid.NewString()) - log.Info().Str("File", manifestFile).Msg("Creating manifest") - if err := os.WriteFile(manifestFile, []byte(manifest), os.ModePerm); err != nil { - return err - } - cmd := fmt.Sprintf("kubectl create -f %s", manifestFile) - return ExecCmd(cmd) -} - -// DryRun generates manifest and writes it in a file -func (m *K8sClient) DryRun(manifest string) error { - manifestFile := fmt.Sprintf(TempDebugManifest, uuid.NewString()) - log.Info().Str("File", manifestFile).Msg("Creating manifest") - return os.WriteFile(manifestFile, []byte(manifest), os.ModePerm) -} - -// CopyToPod copies src to a particular container. Destination should be in the form of a proper K8s destination path -// NAMESPACE/POD_NAME:folder/FILE_NAME -func (m *K8sClient) CopyToPod(namespace, src, destination, containername string) (*bytes.Buffer, *bytes.Buffer, *bytes.Buffer, error) { - m.RESTConfig.APIPath = "/api" - m.RESTConfig.GroupVersion = &schema.GroupVersion{Version: "v1"} // this targets the core api groups so the url path will be /api/v1 - m.RESTConfig.NegotiatedSerializer = serializer.WithoutConversionCodecFactory{CodecFactory: scheme.Codecs} - ioStreams, in, out, errOut := genericclioptions.NewTestIOStreams() - - copyOptions := cp.NewCopyOptions(ioStreams) - configFlags := genericclioptions.NewConfigFlags(false) - f := cmdutil.NewFactory(configFlags) - cmd := cp.NewCmdCp(f, ioStreams) - err := copyOptions.Complete(f, cmd, []string{src, destination}) - if err != nil { - return nil, nil, nil, err - } - copyOptions.Clientset = m.ClientSet - copyOptions.ClientConfig = m.RESTConfig - copyOptions.Container = containername - copyOptions.Namespace = namespace - - formatted, err := regexp.MatchString(".*?\\/.*?\\:.*", destination) - if err != nil { - return nil, nil, nil, fmt.Errorf("could not parse the pod destination: %w", err) - } - if !formatted { - return nil, nil, nil, fmt.Errorf("pod destination string improperly formatted, see reference 'NAMESPACE/POD_NAME:folder/FILE_NAME'") - } - - log.Info(). - Str("Namespace", namespace). - Str("Source", src). - Str("Destination", destination). - Str("Container", containername). - Msg("Uploading file to pod") - err = copyOptions.Run() - if err != nil { - return nil, nil, nil, fmt.Errorf("could not run copy operation: %w", err) - } - return in, out, errOut, nil -} - -// ExecuteInPod is similar to kubectl exec -func (m *K8sClient) ExecuteInPod(namespace, podName, containerName string, command []string) ([]byte, []byte, error) { - log.Info().Interface("Command", command).Msg("Executing command in pod") - req := m.ClientSet.CoreV1().RESTClient().Post(). - Resource("pods"). - Name(podName). - Namespace(namespace). - SubResource("exec") - req.VersionedParams(&v1.PodExecOptions{ - Container: containerName, - Command: command, - Stdin: false, - Stdout: true, - Stderr: true, - TTY: false, - }, scheme.ParameterCodec) - - exec, err := remotecommand.NewSPDYExecutor(m.RESTConfig, "POST", req.URL()) - if err != nil { - return []byte{}, []byte{}, err - } - - var stdout, stderr bytes.Buffer - err = exec.StreamWithContext(context.Background(), remotecommand.StreamOptions{ - Stdin: nil, - Stdout: &stdout, - Stderr: &stderr, - }) - return stdout.Bytes(), stderr.Bytes(), err -} - -func podNames(podItems *v1.PodList) []string { - on := make([]string, 0) - for _, p := range podItems.Items { - on = append(on, p.Name) - } - return on -} diff --git a/lib/k8s/client/cmd.go b/lib/k8s/client/cmd.go deleted file mode 100644 index c88aa9bad..000000000 --- a/lib/k8s/client/cmd.go +++ /dev/null @@ -1,79 +0,0 @@ -package client - -import ( - "bufio" - "bytes" - "context" - "io" - "os/exec" - "strings" - - "github.com/rs/zerolog/log" -) - -func ExecCmd(command string) error { - return ExecCmdWithContext(context.Background(), command) -} - -func ExecCmdWithContext(ctx context.Context, command string) error { - return ExecCmdWithOptions(ctx, command, func(m string) { - log.Debug().Str("Text", m).Msg("Std Pipe") - }) -} - -// readStdPipe continuously reads from a given pipe (either stdout or stderr) -// and processes the output line by line using the provided outputFunction. -// It handles lines of any length dynamically without the need for a large predefined buffer. -func readStdPipe(pipe io.ReadCloser, outputFunction func(string)) { - reader := bufio.NewReader(pipe) - var output []rune - - for { - // ReadLine tries to return a single line, not including the end-of-line bytes. - // The returned line may be incomplete if the line's too long for the buffer. - // isPrefix will be true if the line is longer than the buffer. - chunk, isPrefix, err := reader.ReadLine() - - // Handle any errors that occurred during the read. - if err != nil { - // Log any error that's not an EOF (end of file). - if err != io.EOF { - log.Warn().Err(err).Msg("Error while reading standard pipe, this can be caused by really long logs and can be ignored if nothing else is wrong.") - } - break - } - - // Append the chunk to the output buffer. - // bytes.Runes converts the byte slice to a slice of runes, handling multi-byte characters. - output = append(output, bytes.Runes(chunk)...) - - // If isPrefix is false, we've reached the end of the line and can process it. - if !isPrefix { - // Call the output function with the complete line if it's defined. - if outputFunction != nil { - outputFunction(string(output)) - } - // Reset output to an empty slice for reading the next line. - output = output[:0] - } - } -} - -func ExecCmdWithOptions(ctx context.Context, command string, outputFunction func(string)) error { - c := strings.Split(command, " ") - cmd := exec.CommandContext(ctx, c[0], c[1:]...) // #nosec: G204 - stderr, err := cmd.StderrPipe() - if err != nil { - return err - } - stdout, err := cmd.StdoutPipe() - if err != nil { - return err - } - if err := cmd.Start(); err != nil { - return err - } - go readStdPipe(stderr, outputFunction) - go readStdPipe(stdout, outputFunction) - return cmd.Wait() -} diff --git a/lib/k8s/client/cmd_test.go b/lib/k8s/client/cmd_test.go deleted file mode 100644 index 15f7aa28f..000000000 --- a/lib/k8s/client/cmd_test.go +++ /dev/null @@ -1,45 +0,0 @@ -package client - -import ( - "io" - "strings" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestReadStdPipeWithLongString(t *testing.T) { - // Create a string with a million characters ('a'). - longString := strings.Repeat("a", 1000000) - - // Use an io.Pipe to simulate the stdout or stderr pipe. - reader, writer := io.Pipe() - - // Channel to communicate errors from the writing goroutine. - errChan := make(chan error, 1) - - // Write the long string to the pipe in a goroutine. - go func() { - _, err := writer.Write([]byte(longString)) - if err != nil { - // Send any errors to the main test goroutine via the channel. - errChan <- err - } - writer.Close() - errChan <- nil // Send nil to indicate successful write. - }() - - // Variable to store the output from the readStdPipe function. - var output string - outputFunction := func(s string) { - output = s - } - - // Call the readStdPipe function with the reader part of the pipe. - readStdPipe(reader, outputFunction) - - // Check for errors from the write goroutine. - err := <-errChan - require.NoError(t, err, "Failed to write to pipe") - require.Equal(t, longString, output, "Output did not match the input long string") -} diff --git a/lib/k8s/client/converter.go b/lib/k8s/client/converter.go deleted file mode 100644 index 364524742..000000000 --- a/lib/k8s/client/converter.go +++ /dev/null @@ -1,73 +0,0 @@ -package client - -import ( - "errors" - "fmt" -) - -type ConnectionMode int - -const ( - LocalConnection ConnectionMode = iota - RemoteConnection -) - -// Protocol represents a URL scheme to use when fetching connection details -type Protocol int - -const ( - // WS : Web Socket Protocol - WS Protocol = iota - // WSSUFFIX : Web Socket Protocol - WSSUFFIX - // WSS : Web Socket Secure Protocol - WSS - // HTTP : Hypertext Transfer Protocol - HTTP - // HTTPS : Hypertext Transfer Protocol Secure - HTTPS - POSTGRESQL -) - -// URLConverter converts ports to URLs -type URLConverter struct { - ci ConnectionInfo - err error -} - -// NewURLConverter creates new URLConverter instance -func NewURLConverter(fp ConnectionInfo, err error) *URLConverter { - return &URLConverter{fp, err} -} - -// As converts host/port to an URL -func (m *URLConverter) As(conn ConnectionMode, proto Protocol) (string, error) { - if m.err != nil { - return "", m.err - } - var host string - var port uint16 - if conn == RemoteConnection { - host = m.ci.Host - port = m.ci.Ports.Remote - } else { - host = "127.0.0.1" - port = m.ci.Ports.Local - } - switch proto { - case HTTP: - return fmt.Sprintf("http://%s:%d", host, port), nil - case HTTPS: - return fmt.Sprintf("https://%s:%d", host, port), nil - case WS: - return fmt.Sprintf("ws://%s:%d", host, port), nil - case WSSUFFIX: - return fmt.Sprintf("ws://%s:%d/ws", host, port), nil - case WSS: - return fmt.Sprintf("wss://%s:%d", host, port), nil - case POSTGRESQL: - return fmt.Sprintf("postgresql://%s:%d", host, port), nil - default: - return "", errors.New("unknown protocol conversion type") - } -} diff --git a/lib/k8s/client/forwarder.go b/lib/k8s/client/forwarder.go deleted file mode 100644 index a95ada7f0..000000000 --- a/lib/k8s/client/forwarder.go +++ /dev/null @@ -1,204 +0,0 @@ -package client - -import ( - "bytes" - "fmt" - "net/http" - "net/url" - "strings" - "sync" - - "github.com/rs/zerolog/log" - "golang.org/x/sync/errgroup" - v1 "k8s.io/api/core/v1" - "k8s.io/client-go/tools/portforward" - "k8s.io/client-go/transport/spdy" -) - -type Forwarder struct { - Client *K8sClient - mu *sync.Mutex - KeepConnection bool - Info map[string]interface{} -} - -type ConnectionInfo struct { - Ports portforward.ForwardedPort - Host string -} - -func NewForwarder(client *K8sClient, keepConnection bool) *Forwarder { - return &Forwarder{ - Client: client, - mu: &sync.Mutex{}, - KeepConnection: keepConnection, - Info: make(map[string]interface{}), - } -} - -func (m *Forwarder) forwardPodPorts(pod v1.Pod, namespaceName string) error { - if pod.Status.Phase != v1.PodRunning { - log.Debug().Str("Pod", pod.Name).Interface("Phase", pod.Status.Phase).Msg("Skipping pod for port forwarding") - return nil - } - roundTripper, upgrader, err := spdy.RoundTripperFor(m.Client.RESTConfig) - if err != nil { - return err - } - httpPath := fmt.Sprintf("/api/v1/namespaces/%s/pods/%s/portforward", namespaceName, pod.Name) - hostIP := strings.TrimLeft(m.Client.RESTConfig.Host, "htps:/") - serverURL := url.URL{Scheme: "https", Path: httpPath, Host: hostIP} - - dialer := spdy.NewDialer(upgrader, &http.Client{Transport: roundTripper}, http.MethodPost, &serverURL) - - portRules := m.portRulesForPod(pod) - if len(portRules) == 0 { - return nil - } - - // porforward is not thread safe for using multiple rules in the same forwarder, - // at least not until this pr is merged: https://github.com/kubernetes/kubernetes/pull/114342 - forwardedPorts := []portforward.ForwardedPort{} - for _, portRule := range portRules { - stopChan, readyChan := make(chan struct{}, 1), make(chan struct{}, 1) - out, errOut := new(bytes.Buffer), new(bytes.Buffer) - - log.Debug(). - Str("Pod", pod.Name). - Msg("Attempting to forward ports") - - forwarder, err := portforward.New(dialer, []string{portRule}, stopChan, readyChan, out, errOut) - if err != nil { - return err - } - go func() { - if err := forwarder.ForwardPorts(); err != nil { - log.Error().Str("Pod", pod.Name).Err(err) - } - }() - - <-readyChan - if len(errOut.String()) > 0 { - return fmt.Errorf("error on forwarding k8s port: %v", errOut.String()) - } - fP, err := forwarder.GetPorts() - if err != nil { - return err - } - forwardedPorts = append(forwardedPorts, fP...) - } - m.mu.Lock() - defer m.mu.Unlock() - namedPorts := m.podPortsByName(pod, forwardedPorts) - if pod.Labels[AppLabel] != "" { - m.Info[fmt.Sprintf("%s:%s", pod.Labels[AppLabel], pod.Labels["instance"])] = namedPorts - } - return nil -} - -func (m *Forwarder) collectPodPorts(pod v1.Pod) error { - namedPorts := make(map[string]interface{}) - for _, c := range pod.Spec.Containers { - for _, cp := range c.Ports { - if namedPorts[c.Name] == nil { - namedPorts[c.Name] = make(map[string]interface{}) - } - namedPorts[c.Name].(map[string]interface{})[cp.Name] = ConnectionInfo{ - Host: pod.Status.PodIP, - Ports: portforward.ForwardedPort{Remote: uint16(cp.ContainerPort)}, - } - } - } - m.mu.Lock() - defer m.mu.Unlock() - if pod.Labels[AppLabel] != "" { - m.Info[fmt.Sprintf("%s:%s", pod.Labels[AppLabel], pod.Labels["instance"])] = namedPorts - } - return nil -} - -func (m *Forwarder) podPortsByName(pod v1.Pod, fp []portforward.ForwardedPort) map[string]interface{} { - ports := make(map[string]interface{}) - for _, forwardedPort := range fp { - for _, c := range pod.Spec.Containers { - for _, cp := range c.Ports { - if cp.ContainerPort == int32(forwardedPort.Remote) { - if ports[c.Name] == nil { - ports[c.Name] = make(map[string]interface{}) - } - ports[c.Name].(map[string]interface{})[cp.Name] = ConnectionInfo{ - Host: pod.Status.PodIP, - Ports: forwardedPort, - } - } - } - } - } - return ports -} - -func (m *Forwarder) portRulesForPod(pod v1.Pod) []string { - rules := make([]string, 0) - for _, c := range pod.Spec.Containers { - for _, port := range c.Ports { - rules = append(rules, fmt.Sprintf(":%d", port.ContainerPort)) - } - } - return rules -} - -func (m *Forwarder) Connect(namespaceName string, selector string, insideK8s bool) error { - m.Info = make(map[string]interface{}) - pods, err := m.Client.ListPods(namespaceName, selector) - if err != nil { - return err - } - eg := &errgroup.Group{} - for _, p := range pods.Items { - p := p - if insideK8s { - eg.Go(func() error { - return m.collectPodPorts(p) - }) - } else { - eg.Go(func() error { - return m.forwardPodPorts(p, namespaceName) - }) - } - } - return eg.Wait() -} - -// PrintLocalPorts prints all local forwarded ports -func (m *Forwarder) PrintLocalPorts() { - for labeledAppPodName, labeledAppPod := range m.Info { - for containerName, container := range labeledAppPod.(map[string]interface{}) { - for fpName, portsData := range container.(map[string]interface{}) { - log.Info(). - Str("Label", labeledAppPodName). - Str("Container", containerName). - Str("PortNames", fpName). - Uint16("Port", portsData.(ConnectionInfo).Ports.Local). - Msg("Local ports") - } - } - } -} - -func (m *Forwarder) FindPort(ks ...string) *URLConverter { - d, err := lookupMap(m.Info, ks...) - return NewURLConverter(d.(ConnectionInfo), err) -} - -func lookupMap(m map[string]interface{}, ks ...string) (rval interface{}, err error) { - var ok bool - if len(ks) == 0 { - return nil, fmt.Errorf("select port path like $app_name:$instance $container_name $port_name") - } - if rval, ok = m[ks[0]]; !ok { - return ConnectionInfo{}, fmt.Errorf("key not found: '%s' remaining keys: %s, provided map: %s", ks[0], ks, m) - } else if len(ks) == 1 { - return rval, nil - } - return lookupMap(m[ks[0]].(map[string]interface{}), ks[1:]...) -} diff --git a/lib/k8s/config/overrides.go b/lib/k8s/config/config.go similarity index 100% rename from lib/k8s/config/overrides.go rename to lib/k8s/config/config.go diff --git a/lib/k8s/config/overrides_test.go b/lib/k8s/config/overrides_test.go deleted file mode 100644 index 780511d6b..000000000 --- a/lib/k8s/config/overrides_test.go +++ /dev/null @@ -1,59 +0,0 @@ -package config - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -type Props struct { - Name string `envconfig:"MY_NAME" yaml:"name"` -} - -func TestOverrideCodeEnv(t *testing.T) { - t.Run("CL env and version", func(t *testing.T) { - defaultCodeProps := map[string]interface{}{ - "replicas": "1", - "env": map[string]interface{}{ - "database_url": "postgresql://postgres:node@0.0.0.0/chainlink?sslmode=disable", - }, - "chainlink": map[string]interface{}{ - "image": map[string]interface{}{ - "image": "public.ecr.aws/chainlink/chainlink", - "version": "1.4.1-root", - }, - "web_port": "6688", - "p2p_port": "6690", - "resources": map[string]interface{}{ - "requests": map[string]interface{}{ - "cpu": "350m", - "memory": "1024Mi", - }, - "limits": map[string]interface{}{ - "cpu": "350m", - "memory": "1024Mi", - }, - }, - }, - "db": map[string]interface{}{ - "stateful": false, - "capacity": "1Gi", - "resources": map[string]interface{}{ - "requests": map[string]interface{}{ - "cpu": "250m", - "memory": "256Mi", - }, - "limits": map[string]interface{}{ - "cpu": "250m", - "memory": "256Mi", - }, - }, - }, - } - t.Setenv(EnvVarCLImage, "abc") - t.Setenv(EnvVarCLTag, "def") - MustEnvOverrideVersion(&defaultCodeProps) - require.Equal(t, "abc", defaultCodeProps["chainlink"].(map[string]interface{})["image"].(map[string]interface{})["image"]) - require.Equal(t, "def", defaultCodeProps["chainlink"].(map[string]interface{})["image"].(map[string]interface{})["version"]) - }) -} diff --git a/lib/k8s/e2e/common/test_common.go b/lib/k8s/e2e/common/test_common.go deleted file mode 100644 index ae412f34e..000000000 --- a/lib/k8s/e2e/common/test_common.go +++ /dev/null @@ -1,489 +0,0 @@ -package common - -import ( - "fmt" - "os" - "strconv" - "strings" - "testing" - "time" - - "github.com/go-resty/resty/v2" - "github.com/onsi/gomega" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/chaos" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/client" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/config" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/environment" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/chainlink" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/ethereum" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/presets" - "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" - "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/ptr" -) - -const ( - TestEnvType = "chainlink-testing-framework-k8s-test" -) - -var ( - testSelector = fmt.Sprintf("envType=%s", TestEnvType) -) - -func GetTestEnvConfig(t *testing.T) *environment.Config { - testType := "functional" - product := "internal-k8s-test-runner" - - nsLabels, err := environment.GetRequiredChainLinkNamespaceLabels(product, testType) - require.NoError(t, err, "Error creating required chain.link labels for namespace") - - workloadPodLabels, err := environment.GetRequiredChainLinkWorkloadAndPodLabels(product, testType) - require.NoError(t, err, "Error creating required chain.link labels for workloads and pods") - - return &environment.Config{ - NamespacePrefix: TestEnvType, - Test: t, - Labels: nsLabels, - WorkloadLabels: workloadPodLabels, - PodLabels: workloadPodLabels, - SkipRequiredChainLinkLabelsValidation: true, - } -} - -func TestMultiStageMultiManifestConnection(t *testing.T) { - t.Parallel() - l := logging.GetTestLogger(t) - testEnvConfig := GetTestEnvConfig(t) - - ethChart := ethereum.New(nil) - ethNetworkName := ethChart.GetProps().(*ethereum.Props).NetworkName - - // we adding the same chart with different index and executing multi-stage deployment - // connections should be renewed - e := environment.New(testEnvConfig) - err := e.AddHelm(ethChart). - AddHelm(chainlink.New(0, map[string]any{ - "replicas": 1, - "toml": presets.BaseToml, - })). - Run() - require.NoError(t, err) - if e.WillUseRemoteRunner() { - return - } - t.Cleanup(func() { - assert.NoError(t, e.Shutdown()) - }) - require.Len(t, e.URLs[chainlink.NodesLocalURLsKey], 1) - require.Len(t, e.URLs[chainlink.NodesInternalURLsKey], 1) - require.Len(t, e.URLs[chainlink.DBsLocalURLsKey], 1) - require.Len(t, e.URLs, 7) - - err = e.AddHelm(chainlink.New(1, map[string]any{ - "replicas": 1, - "toml": presets.BaseToml, - })). - Run() - require.NoError(t, err) - require.Len(t, e.URLs[chainlink.NodesLocalURLsKey], 2) - require.Len(t, e.URLs[chainlink.NodesInternalURLsKey], 2) - require.Len(t, e.URLs[chainlink.DBsLocalURLsKey], 2) - require.Len(t, e.URLs, 7) - - urls := make([]string, 0) - if e.Cfg.InsideK8s { - urls = append(urls, e.URLs[chainlink.NodesInternalURLsKey]...) - urls = append(urls, e.URLs[ethNetworkName+"_internal_http"]...) - } else { - urls = append(urls, e.URLs[chainlink.NodesLocalURLsKey]...) - urls = append(urls, e.URLs[ethNetworkName+"_http"]...) - } - - r := resty.New() - for _, u := range urls { - l.Info().Str("URL", u).Send() - res, err := r.R().Get(u) - require.NoError(t, err) - require.Equal(t, "200 OK", res.Status()) - } -} - -func TestConnectWithoutManifest(t *testing.T) { - l := logging.GetTestLogger(t) - existingEnvConfig := GetTestEnvConfig(t) - testEnvConfig := GetTestEnvConfig(t) - existingEnvAlreadySetupVar := "ENV_ALREADY_EXISTS" - var existingEnv *environment.Environment - - // only run this section if we don't already have an existing environment - // needed for remote runner based tests to prevent duplicate envs from being created - if os.Getenv(existingEnvAlreadySetupVar) == "" { - existingEnv = environment.New(existingEnvConfig) - l.Info().Str("Namespace", existingEnvConfig.Namespace).Msg("Existing Env Namespace") - // deploy environment to use as an existing one for the test - require.NotNil(t, existingEnv, "existingEnv is nil") - require.NotNil(t, existingEnv.Cfg, "existingEnv.Cfg is nil %v", existingEnv) - existingEnv.Cfg.JobImage = "" - existingEnv.AddHelm(ethereum.New(nil)). - AddHelm(chainlink.New(0, map[string]any{ - "replicas": 1, - "toml": presets.BaseToml, - })) - err := existingEnv.Run() - require.NoError(t, err) - // propagate the existing environment to the remote runner - t.Setenv(fmt.Sprintf("TEST_%s", existingEnvAlreadySetupVar), "abc") - // set the namespace to the existing one for local runs - testEnvConfig.Namespace = existingEnv.Cfg.Namespace - } else { - l.Info().Msg("Environment already exists, verifying it is correct") - require.NotEmpty(t, os.Getenv(config.EnvVarNamespace)) - skipManifestUpdate, err := strconv.ParseBool(os.Getenv(config.EnvVarSkipManifestUpdate)) - require.NoError(t, err, "Failed to parse the no manifest update env var") - require.True(t, skipManifestUpdate) - } - - // Now run an environment without a manifest like a normal test - testEnvConfig.SkipManifestUpdate = true - testEnv := environment.New(testEnvConfig) - l.Info().Msgf("Testing Env Namespace %s", testEnv.Cfg.Namespace) - err := testEnv.AddHelm(ethereum.New(nil)). - AddHelm(chainlink.New(0, map[string]any{ - "replicas": 1, - "toml": presets.BaseToml, - })). - Run() - require.NoError(t, err) - if testEnv.WillUseRemoteRunner() { - return - } - t.Cleanup(func() { - assert.NoError(t, testEnv.Shutdown()) - }) - - connection := client.LocalConnection - if testEnv.Cfg.InsideK8s { - connection = client.RemoteConnection - } - url, err := testEnv.Fwd.FindPort("chainlink-0:node-1", "node", "access").As(connection, client.HTTP) - require.NoError(t, err) - urlGeth, err := testEnv.Fwd.FindPort("geth:0", "geth-network", "http-rpc").As(connection, client.HTTP) - require.NoError(t, err) - r := resty.New() - l.Info().Msgf("getting url: %s", url) - res, err := r.R().Get(url) - require.NoError(t, err) - require.Equal(t, "200 OK", res.Status()) - l.Info().Msgf("getting url: %s", url) - res, err = r.R().Get(urlGeth) - require.NoError(t, err) - require.Equal(t, "200 OK", res.Status()) - l.Info().Msgf("done getting url: %s", url) -} - -func Test5NodesSoakEnvironmentWithPVCs(t *testing.T) { - t.Parallel() - testEnvConfig := GetTestEnvConfig(t) - e := presets.EVMSoak(testEnvConfig) - err := e.Run() - require.NoError(t, err) - t.Cleanup(func() { - assert.NoError(t, e.Shutdown()) - }) -} - -func TestWithSingleNodeEnvParallel(t *testing.T) { - t.Parallel() - TestWithSingleNodeEnv(t) -} - -func TestWithSingleNodeEnv(t *testing.T) { - testEnvConfig := GetTestEnvConfig(t) - e, err := presets.EVMOneNode(testEnvConfig) - require.NoError(t, err) - err = e.Run() - require.NoError(t, err) - if e.WillUseRemoteRunner() { - return - } - t.Cleanup(func() { - assert.NoError(t, e.Shutdown()) - }) -} - -func TestMultipleNodeWithDiffDBVersionEnv(t *testing.T) { - t.Parallel() - testEnvConfig := GetTestEnvConfig(t) - e := presets.EVMMultipleNodesWithDiffDBVersion(testEnvConfig) - err := e.Run() - require.NoError(t, err) - if e.WillUseRemoteRunner() { - return - } - t.Cleanup(func() { - assert.NoError(t, e.Shutdown()) - }) -} - -func TestMinResources5NodesEnv(t *testing.T) { - t.Parallel() - testEnvConfig := GetTestEnvConfig(t) - e := presets.EVMMinimalLocal(testEnvConfig) - err := e.Run() - require.NoError(t, err) - if e.WillUseRemoteRunner() { - return - } - t.Cleanup(func() { - assert.NoError(t, e.Shutdown()) - }) -} - -func TestMinResources5NodesEnvWithBlockscout(t *testing.T) { - t.Parallel() - testEnvConfig := GetTestEnvConfig(t) - e, err := presets.EVMMinimalLocalBS(testEnvConfig) - require.NoError(t, err) - err = e.Run() - require.NoError(t, err) - if e.WillUseRemoteRunner() { - return - } - t.Cleanup(func() { - assert.NoError(t, e.Shutdown()) - }) -} - -func Test5NodesPlus2MiningGethsReorgEnv(t *testing.T) { - t.Parallel() - testEnvConfig := GetTestEnvConfig(t) - e, err := presets.EVMReorg(testEnvConfig) - require.NoError(t, err) - err = e.Run() - require.NoError(t, err) - if e.WillUseRemoteRunner() { - return - } - t.Cleanup(func() { - assert.NoError(t, e.Shutdown()) - }) -} - -func TestMultipleInstancesOfTheSameType(t *testing.T) { - t.Parallel() - testEnvConfig := GetTestEnvConfig(t) - e := environment.New(testEnvConfig). - AddHelm(ethereum.New(nil)). - AddHelm(chainlink.New(0, map[string]any{ - "replicas": 1, - "toml": presets.BaseToml, - })). - AddHelm(chainlink.New(1, map[string]any{ - "replicas": 1, - "toml": presets.BaseToml, - })) - err := e.Run() - require.NoError(t, err) - if e.WillUseRemoteRunner() { - return - } - t.Cleanup(func() { - assert.NoError(t, e.Shutdown()) - }) -} - -// TestWithChaos runs a test with chaos injected into the environment. -func TestWithChaos(t *testing.T) { - t.Parallel() - l := logging.GetTestLogger(t) - appLabel := "chainlink-0" - testCase := struct { - chaosFunc chaos.ManifestFunc - chaosProps *chaos.Props - }{ - chaos.NewFailPods, - &chaos.Props{ - LabelsSelector: &map[string]*string{client.AppLabel: ptr.Ptr(appLabel)}, - DurationStr: "30s", - }, - } - testEnvConfig := GetTestEnvConfig(t) - cd := chainlink.New(0, map[string]any{ - "replicas": 1, - "toml": presets.BaseToml, - }) - - e := environment.New(testEnvConfig). - AddHelm(ethereum.New(nil)). - AddHelm(cd) - err := e.Run() - require.NoError(t, err) - if e.WillUseRemoteRunner() { - return - } - t.Cleanup(func() { - assert.NoError(t, e.Shutdown()) - }) - - url := e.URLs["chainlink_local"][0] - r := resty.New() - res, err := r.R().Get(url) - require.NoError(t, err) - require.Equal(t, "200 OK", res.Status()) - - // start chaos - _, err = e.Chaos.Run(testCase.chaosFunc(e.Cfg.Namespace, testCase.chaosProps)) - require.NoError(t, err) - gom := gomega.NewGomegaWithT(t) - gom.Eventually(func(g gomega.Gomega) { - res, err = r.R().Get(url) - g.Expect(err).Should(gomega.HaveOccurred()) - l.Info().Msg("Expected error was found") - }, "1m", "3s").Should(gomega.Succeed()) - - l.Info().Msg("Waiting for Pod to start back up") - err = e.Run() - require.NoError(t, err) - - // verify that the node can receive requests again - url = e.URLs["chainlink_local"][0] - res, err = r.R().Get(url) - require.NoError(t, err) - require.Equal(t, "200 OK", res.Status()) -} - -func TestEmptyEnvironmentStartup(t *testing.T) { - t.Parallel() - testEnvConfig := GetTestEnvConfig(t) - e := environment.New(testEnvConfig) - err := e.Run() - require.NoError(t, err) - if e.WillUseRemoteRunner() { - return - } - t.Cleanup(func() { - assert.NoError(t, e.Shutdown()) - }) -} - -func TestRolloutRestart(t *testing.T, statefulSet bool) { - t.Parallel() - testEnvConfig := GetTestEnvConfig(t) - cd := chainlink.New(0, map[string]any{ - "replicas": 5, - "toml": presets.BaseToml, - "db": map[string]any{ - "stateful": true, - "capacity": "1Gi", - }, - }) - - e := environment.New(testEnvConfig). - AddHelm(ethereum.New(nil)). - AddHelm(cd) - err := e.Run() - require.NoError(t, err) - if e.WillUseRemoteRunner() { - return - } - t.Cleanup(func() { - assert.NoError(t, e.Shutdown()) - }) - - if statefulSet { - err = e.RolloutStatefulSets() - require.NoError(t, err, "failed to rollout statefulsets") - } else { - err = e.RolloutRestartBySelector("deployment", testSelector) - require.NoError(t, err, "failed to rollout restart deployment") - } - - err = e.Run() - require.NoError(t, err, "failed to run environment") -} - -func TestReplaceHelm(t *testing.T) { - t.Parallel() - testEnvConfig := GetTestEnvConfig(t) - cd := chainlink.New(0, map[string]any{ - "toml": presets.BaseToml, - "chainlink": map[string]any{ - "resources": map[string]any{ - "requests": map[string]any{ - "cpu": "350m", - }, - "limits": map[string]any{ - "cpu": "350m", - }, - }, - }, - }) - - e := environment.New(testEnvConfig).AddHelm(cd) - err := e.Run() - require.NoError(t, err) - if e.WillUseRemoteRunner() { - return - } - t.Cleanup(func() { - assert.NoError(t, e.Shutdown()) - }) - require.NoError(t, err) - cd = chainlink.New(1, map[string]any{ - "toml": presets.BaseToml, - "chainlink": map[string]any{ - "resources": map[string]any{ - "requests": map[string]any{ - "cpu": "345m", - }, - "limits": map[string]any{ - "cpu": "345m", - }, - }, - }, - }) - require.NoError(t, err) - e, err = e. - ReplaceHelm("chainlink-0", cd) - require.NoError(t, err) - err = e.Run() - require.NoError(t, err) -} - -func TestRunTimeout(t *testing.T) { - t.Parallel() - testEnvConfig := GetTestEnvConfig(t) - e, err := presets.EVMOneNode(testEnvConfig) - require.NoError(t, err) - e.Cfg.ReadyCheckData.Timeout = 5 * time.Second - err = e.Run() - require.Error(t, err) -} - -func TestReallyLongLogs(t *testing.T) { - t.Parallel() - l := logging.GetTestLogger(t) - testEnvConfig := GetTestEnvConfig(t) - val, _ := os.LookupEnv(config.EnvVarJobImage) - if val != "" { - env := environment.New(testEnvConfig) - err := env.Run() - require.NoError(t, err) - } - s := strings.Repeat("a", 500000) - // this shouldn't hang - l.Info().Int("len", len(s)).Str("string", s).Msg("string") -} - -func TestAnvil(t *testing.T) { - t.Parallel() - testEnvConfig := GetTestEnvConfig(t) - e := presets.FoundryNetwork(testEnvConfig) - err := e.Run() - require.NoError(t, err) - t.Cleanup(func() { - assert.NoError(t, e.Shutdown()) - }) -} diff --git a/lib/k8s/e2e/local-runner/envs_test.go b/lib/k8s/e2e/local-runner/envs_test.go deleted file mode 100644 index 6d66ea12d..000000000 --- a/lib/k8s/e2e/local-runner/envs_test.go +++ /dev/null @@ -1,82 +0,0 @@ -package env_test - -import ( - "testing" - - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/config" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/e2e/common" -) - -func TestMultiStageMultiManifestConnection(t *testing.T) { - common.TestMultiStageMultiManifestConnection(t) -} - -func TestConnectWithoutManifest(t *testing.T) { - common.TestConnectWithoutManifest(t) -} - -func Test5NodesSoakEnvironmentWithPVCs(t *testing.T) { - common.Test5NodesSoakEnvironmentWithPVCs(t) -} - -func TestWithSingleNodeEnv(t *testing.T) { - common.TestWithSingleNodeEnvParallel(t) -} - -func TestWithSingleNodeEnvLocalCharts(t *testing.T) { - t.Setenv(config.EnvVarLocalCharts, "true") - common.TestWithSingleNodeEnv(t) -} - -func TestMultipleNodeWithDiffDBVersionEnv(t *testing.T) { - common.TestMultipleNodeWithDiffDBVersionEnv(t) -} - -func TestMinResources5NodesEnv(t *testing.T) { - common.TestMinResources5NodesEnv(t) -} - -func TestMinResources5NodesEnvWithBlockscout(t *testing.T) { - common.TestMinResources5NodesEnvWithBlockscout(t) -} - -func TestMultipleInstancesOfTheSameType(t *testing.T) { - common.TestMultipleInstancesOfTheSameType(t) -} - -func Test5NodesPlus2MiningGethsReorgEnv(t *testing.T) { - common.Test5NodesPlus2MiningGethsReorgEnv(t) -} - -func TestWithChaos(t *testing.T) { - common.TestWithChaos(t) -} - -func TestEmptyEnvironmentStartup(t *testing.T) { - common.TestEmptyEnvironmentStartup(t) -} - -func TestRolloutRestartUpdate(t *testing.T) { - t.Skip("Always fails") - common.TestRolloutRestart(t, true) -} - -func TestRolloutRestartBySelector(t *testing.T) { - common.TestRolloutRestart(t, false) -} - -func TestReplaceHelm(t *testing.T) { - common.TestReplaceHelm(t) -} - -func TestRunTimeout(t *testing.T) { - common.TestRunTimeout(t) -} - -func TestReallyLongLogs(t *testing.T) { - common.TestReallyLongLogs(t) -} - -func TestWithAnvil(t *testing.T) { - common.TestAnvil(t) -} diff --git a/lib/k8s/e2e/remote-runner/remote_runner_envs_test.go b/lib/k8s/e2e/remote-runner/remote_runner_envs_test.go deleted file mode 100644 index 15404abd4..000000000 --- a/lib/k8s/e2e/remote-runner/remote_runner_envs_test.go +++ /dev/null @@ -1,195 +0,0 @@ -package e2e_remote_runner_test - -import ( - "fmt" - "testing" - "time" - - "github.com/go-resty/resty/v2" - "github.com/rs/zerolog/log" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/config" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/e2e/common" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/environment" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/chainlink" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/ethereum" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/mockserver" - mockservercfg "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/mockserver-cfg" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/presets" -) - -func TestMultiStageMultiManifestConnection(t *testing.T) { - common.TestMultiStageMultiManifestConnection(t) -} - -func TestConnectWithoutManifest(t *testing.T) { - common.TestConnectWithoutManifest(t) -} - -func Test5NodesSoakEnvironmentWithPVCs(t *testing.T) { - common.Test5NodesSoakEnvironmentWithPVCs(t) -} - -func TestWithSingleNodeEnv(t *testing.T) { - common.TestWithSingleNodeEnvParallel(t) -} - -func TestWithSingleNodeEnvLocalCharts(t *testing.T) { - t.Setenv(config.EnvVarLocalCharts, "true") - common.TestWithSingleNodeEnv(t) -} - -func TestMultipleNodeWithDiffDBVersionEnv(t *testing.T) { - common.TestMultipleNodeWithDiffDBVersionEnv(t) -} - -func TestMinResources5NodesEnv(t *testing.T) { - common.TestMinResources5NodesEnv(t) -} - -func TestMinResources5NodesEnvWithBlockscout(t *testing.T) { - common.TestMinResources5NodesEnvWithBlockscout(t) -} - -func TestMultipleInstancesOfTheSameType(t *testing.T) { - common.TestMultipleInstancesOfTheSameType(t) -} - -func Test5NodesPlus2MiningGethsReorgEnv(t *testing.T) { - common.Test5NodesPlus2MiningGethsReorgEnv(t) -} - -func TestWithChaos(t *testing.T) { - common.TestWithChaos(t) -} - -func TestFundReturnShutdownLogic(t *testing.T) { - t.Parallel() - testEnvConfig := common.GetTestEnvConfig(t) - e := presets.EVMMinimalLocal(testEnvConfig) - err := e.Run() - if e.WillUseRemoteRunner() { - require.Error(t, err, "Should return an error") - return - } - t.Cleanup(func() { - assert.NoError(t, e.Shutdown()) - }) - require.NoError(t, err) - fmt.Println(environment.FAILED_FUND_RETURN) -} - -func TestFailedTestLogic(t *testing.T) { - t.Skip("This test is meant to fail, and can only be evaluated by looking at the logs. Only turn on if checking this specific logic.") - t.Parallel() - testEnvConfig := common.GetTestEnvConfig(t) - e := presets.OnlyRemoteRunner(testEnvConfig) - err := e.Run() - if e.WillUseRemoteRunner() { - fmt.Println("Inside K8s?", e.Cfg.InsideK8s) - fmt.Println("Test Failed?", e.Cfg.Test.Failed()) - require.True(t, e.Cfg.Test.Failed(), "Test should have failed") - fmt.Println("This is a test-of-a-test and is confusing. The test that this tests should fail. But that also means this tests fails. If you're reading this, the test has actually passed.") - return - } - t.Cleanup(func() { - assert.NoError(t, e.Shutdown()) - }) - require.NoError(t, err) - fmt.Println("Inside K8s?", e.Cfg.InsideK8s) - fmt.Println(environment.TEST_FAILED) -} - -func TestRemoteRunnerOneSetupWithMultipleTests(t *testing.T) { - t.Parallel() - testEnvConfig := common.GetTestEnvConfig(t) - ethChart := ethereum.New(nil) - e := environment.New(testEnvConfig). - AddHelm(mockservercfg.New(nil)). - AddHelm(mockserver.New(nil)). - AddHelm(ethChart). - AddHelm(chainlink.New(0, map[string]any{ - "replicas": 5, - "toml": presets.BaseToml, - })) - err := e.Run() - t.Cleanup(func() { - assert.NoError(t, e.Shutdown()) - }) - require.NoError(t, err) - if e.WillUseRemoteRunner() { - return - } - - // setup of variables to use for verification in a t.Run - ethNetworkName := ethChart.GetProps().(*ethereum.Props).NetworkName - urls := make([]string, 0) - if e.Cfg.InsideK8s { - urls = append(urls, e.URLs[chainlink.NodesInternalURLsKey]...) - urls = append(urls, e.URLs[ethNetworkName+"_internal_http"]...) - } else { - urls = append(urls, e.URLs[chainlink.NodesLocalURLsKey]...) - urls = append(urls, e.URLs[ethNetworkName+"_http"]...) - } - - log.Info().Str("Test", "Before").Msg("Before Tests") - - // This test will verify we can connect a t.Run to the env of the parent test - t.Run("do one", func(t1 *testing.T) { - t1.Parallel() - test1EnvConfig := common.GetTestEnvConfig(t1) - test1EnvConfig.Namespace = e.Cfg.Namespace - test1EnvConfig.SkipManifestUpdate = true - e1 := presets.EVMMinimalLocal(test1EnvConfig) - err := e1.Run() - require.NoError(t1, err) - log.Info().Str("Test", "One").Msg("Inside test") - time.Sleep(1 * time.Second) - }) - - // This test will verify the sub t.Run properly uses the variables from the parent test - t.Run("do two", func(t2 *testing.T) { - t2.Parallel() - log.Info().Str("Test", "Two").Msg("Inside test") - r := resty.New() - for _, u := range urls { - log.Info().Str("URL", u).Send() - res, err := r.R().Get(u) - require.NoError(t2, err) - require.Equal(t2, "200 OK", res.Status()) - } - }) - - log.Info().Str("Test", "After").Msg("After Tests") -} - -func TestEmptyEnvironmentStartup(t *testing.T) { - common.TestEmptyEnvironmentStartup(t) -} - -func TestRolloutRestartUpdate(t *testing.T) { - t.Skip("Always fails") - common.TestRolloutRestart(t, true) -} - -func TestRolloutRestartBySelector(t *testing.T) { - common.TestRolloutRestart(t, false) -} - -func TestReplaceHelm(t *testing.T) { - common.TestReplaceHelm(t) -} - -func TestRunTimeout(t *testing.T) { - common.TestRunTimeout(t) -} - -func TestReallyLongLogs(t *testing.T) { - common.TestReallyLongLogs(t) -} - -func TestWithAnvil(t *testing.T) { - common.TestAnvil(t) -} diff --git a/lib/k8s/environment/artifacts.go b/lib/k8s/environment/artifacts.go deleted file mode 100644 index 49cc7db0e..000000000 --- a/lib/k8s/environment/artifacts.go +++ /dev/null @@ -1,177 +0,0 @@ -package environment - -import ( - "bytes" - "context" - "fmt" - "io" - "os" - "path/filepath" - "strings" - - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/client" - - "github.com/rs/zerolog/log" - coreV1 "k8s.io/api/core/v1" - metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/kubernetes/scheme" - clientV1 "k8s.io/client-go/kubernetes/typed/core/v1" - "k8s.io/client-go/tools/remotecommand" -) - -// Artifacts is an artifacts dumping structure that copies logs and database dumps for all deployed pods -type Artifacts struct { - Namespace string - DBName string - Client *client.K8sClient - podsClient clientV1.PodInterface -} - -// NewArtifacts create new artifacts instance for provided environment -func NewArtifacts(client *client.K8sClient, namespace string) (*Artifacts, error) { - return &Artifacts{ - Namespace: namespace, - Client: client, - podsClient: client.ClientSet.CoreV1().Pods(namespace), - }, nil -} - -// DumpTestResult dumps all pods logs and db dump in a separate test dir -func (a *Artifacts) DumpTestResult(testDir string, dbName string) error { - a.DBName = dbName - if err := MkdirIfNotExists(testDir); err != nil { - return err - } - return a.writePodArtifacts(testDir) -} - -func (a *Artifacts) writePodArtifacts(testDir string) error { - log.Info(). - Str("Test", testDir). - Msg("Writing test artifacts") - podsList, err := a.podsClient.List(context.Background(), metaV1.ListOptions{}) - if err != nil { - log.Err(err). - Str("Namespace", a.Namespace). - Msg("Error retrieving pod list from K8s environment") - return err - } - for _, pod := range podsList.Items { - log.Info(). - Str("Pod", pod.Name). - Msg("Writing pod artifacts") - appName := pod.Labels[client.AppLabel] - instance := pod.Labels["instance"] - appDir := filepath.Join(testDir, fmt.Sprintf("%s_%s", appName, instance)) - if err := MkdirIfNotExists(appDir); err != nil { - return err - } - err = a.writePodLogs(pod, appDir) - if err != nil { - log.Err(err). - Str("Namespace", a.Namespace). - Str("Pod", pod.Name). - Msg("Error writing logs for pod") - } - } - return nil -} - -func (a *Artifacts) dumpDB(pod coreV1.Pod, container coreV1.Container) (string, error) { - postRequestBase := a.Client.ClientSet.CoreV1().RESTClient().Post(). - Namespace(pod.Namespace).Resource("pods").Name(pod.Name).SubResource("exec") - exportDBRequest := postRequestBase.VersionedParams( - &coreV1.PodExecOptions{ - Container: container.Name, - Command: []string{"/bin/sh", "-c", "pg_dump", a.DBName}, - Stdin: true, - Stdout: true, - Stderr: true, - TTY: false, - }, scheme.ParameterCodec) - exec, err := remotecommand.NewSPDYExecutor(a.Client.RESTConfig, "POST", exportDBRequest.URL()) - if err != nil { - return "", err - } - outBuff, errBuff := &bytes.Buffer{}, &bytes.Buffer{} - err = exec.StreamWithContext(context.Background(), remotecommand.StreamOptions{ - Stdin: &bytes.Reader{}, - Stdout: outBuff, - Stderr: errBuff, - Tty: false, - }) - if err != nil || errBuff.Len() > 0 { - return "", fmt.Errorf("error in dumping DB contents | STDOUT: %v | STDERR: %v", outBuff.String(), - errBuff.String()) - } - return outBuff.String(), err -} - -func (a *Artifacts) writePostgresDump(podDir string, pod coreV1.Pod, cont coreV1.Container) error { - dumpContents, err := a.dumpDB(pod, cont) - if err != nil { - return err - } - logFile, err := os.Create(filepath.Join(podDir, fmt.Sprintf("%s_dump.sql", cont.Name))) - if err != nil { - return err - } - _, err = logFile.WriteString(dumpContents) - if err != nil { - return err - } - return logFile.Close() -} - -func (a *Artifacts) writeContainerLogs(podDir string, pod coreV1.Pod, cont coreV1.Container) error { - logFile, err := os.Create(filepath.Join(podDir, cont.Name) + ".log") - if err != nil { - return err - } - podLogRequest := a.podsClient.GetLogs(pod.Name, &coreV1.PodLogOptions{Container: cont.Name}) - podLogs, err := podLogRequest.Stream(context.Background()) - if err != nil { - return err - } - buf := new(bytes.Buffer) - _, err = io.Copy(buf, podLogs) - if err != nil { - return err - } - _, err = logFile.Write(buf.Bytes()) - if err != nil { - return err - } - - if err = logFile.Close(); err != nil { - return err - } - return podLogs.Close() -} - -// Writes logs for each container in a pod -func (a *Artifacts) writePodLogs(pod coreV1.Pod, appDir string) error { - for _, c := range pod.Spec.Containers { - log.Info(). - Str("Container", c.Name). - Msg("Writing container artifacts") - if err := a.writeContainerLogs(appDir, pod, c); err != nil { - return err - } - if strings.Contains(c.Image, "postgres") { - if err := a.writePostgresDump(appDir, pod, c); err != nil { - return err - } - } - } - return nil -} - -func MkdirIfNotExists(dirName string) error { - if _, err := os.Stat(dirName); os.IsNotExist(err) { - if err = os.MkdirAll(dirName, os.ModePerm); err != nil { - return fmt.Errorf("failed to create directory: %s err: %w", dirName, err) - } - } - return nil -} diff --git a/lib/k8s/environment/environment.go b/lib/k8s/environment/environment.go deleted file mode 100644 index 68b4d9691..000000000 --- a/lib/k8s/environment/environment.go +++ /dev/null @@ -1,1459 +0,0 @@ -package environment - -import ( - "context" - "errors" - "fmt" - "os" - "os/signal" - "strconv" - "strings" - "syscall" - "testing" - "time" - - "github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2" - "github.com/go-resty/resty/v2" - "github.com/google/uuid" - "github.com/imdario/mergo" - "github.com/rs/zerolog/log" - "github.com/stretchr/testify/require" - - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/client" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/config" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/imports/k8s" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg" - a "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/alias" - "github.com/smartcontractkit/chainlink-testing-framework/lib/logging" - "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/ptr" - "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" -) - -const ( - COVERAGE_DIR string = "cover" - FAILED_FUND_RETURN string = "FAILED_FUND_RETURN" - TEST_FAILED string = "TEST_FAILED" -) - -const ( - ErrInvalidOCI string = "OCI chart url should be in format oci://$ECR_URL/$ECR_REGISTRY_NAME/$CHART_NAME:[?$CHART_VERSION], was %s" - ErrOCIPull string = "failed to pull OCI repo: %s" -) - -var ( - defaultNamespaceAnnotations = map[string]*string{ - "prometheus.io/scrape": ptr.Ptr("true"), - "backyards.banzaicloud.io/image-registry-access": ptr.Ptr("true"), - "backyards.banzaicloud.io/public-dockerhub-access": ptr.Ptr("true"), - } -) - -// ConnectedChart interface to interact both with cdk8s apps and helm charts -type ConnectedChart interface { - // IsDeploymentNeeded - // true - we deploy/connect and expose environment data - // false - we are using external environment, but still exposing data - IsDeploymentNeeded() bool - // GetName name of the deployed part - GetName() string - // GetPath get Helm chart path, repo or local path - GetPath() string - // GetVersion gets the chart's version, empty string if none is specified - GetVersion() string - // GetProps get code props if it's typed environment - GetProps() any - // GetValues get values.yml props as map, if it's Helm - GetValues() *map[string]any - // ExportData export deployment part data in the env - ExportData(e *Environment) error - // GetLabels returns labels for the component - GetLabels() map[string]string -} - -// Config is an environment common configuration, labels, annotations, connection types, readiness check, etc. -type Config struct { - // TTL is time to live for the environment, used with kyverno - TTL time.Duration - // NamespacePrefix is a static namespace prefix - NamespacePrefix string - // Namespace is full namespace name - Namespace string - // Labels is a set of labels applied to the namespace in a format of "key=value" - Labels []string - // PodLabels is a set of labels applied to every pod in the namespace - PodLabels map[string]string - // WorkloadLabels is a set of labels applied to every workload in the namespace - WorkloadLabels map[string]string - // PreventPodEviction if true sets a k8s annotation safe-to-evict=false to prevent pods from being evicted - // Note: This should only be used if your test is completely incapable of handling things like K8s rebalances without failing. - // If that is the case, it's worth the effort to make your test fault-tolerant soon. The alternative is expensive and infuriating. - PreventPodEviction bool - // Allow deployment to nodes with these tolerances - Tolerations []map[string]string - // Restrict deployment to only nodes matching a particular node role - NodeSelector map[string]string - // ReadyCheckData is settings for readiness probes checks for all deployment components - // checking that all pods are ready by default with 8 minutes timeout - // &client.ReadyCheckData{ - // ReadinessProbeCheckSelector: "", - // Timeout: 15 * time.Minute, - // } - ReadyCheckData *client.ReadyCheckData - // DryRun if true, app will just generate a manifest in local dir - DryRun bool - // InsideK8s used for long-running soak tests where you connect to env from the inside - InsideK8s bool - // SkipManifestUpdate will skip updating the manifest upon connecting to the environment. Should be true if you wish to update the manifest (e.g. upgrade pods) - SkipManifestUpdate bool - // KeepConnection keeps connection until interrupted with a signal, useful when prototyping and debugging a new env - KeepConnection bool - // RemoveOnInterrupt automatically removes an environment on interrupt - RemoveOnInterrupt bool - // UpdateWaitInterval an interval to wait for deployment update started - UpdateWaitInterval time.Duration - - // Remote Runner Specific Variables // - // JobImage an image to run environment as a job inside k8s - JobImage string - // Specify only if you want remote-runner to start with a specific name - RunnerName string - // Specify only if you want to mount reports from test run in remote runner - ReportPath string - // JobLogFunction a function that will be run on each log - JobLogFunction func(*Environment, string) - // Test the testing library current Test struct - Test *testing.T - // jobDeployed used to limit us to 1 remote runner deploy - jobDeployed bool - // detachRunner should we detach the remote runner after starting the test - detachRunner bool - // fundReturnFailed the status of a fund return - fundReturnFailed bool - // Skip validating that all required chain.link labels are present in the final manifest - SkipRequiredChainLinkLabelsValidation bool -} - -func defaultEnvConfig() *Config { - return &Config{ - TTL: 20 * time.Minute, - NamespacePrefix: "chainlink-test-env", - UpdateWaitInterval: 1 * time.Second, - ReadyCheckData: &client.ReadyCheckData{ - ReadinessProbeCheckSelector: "", - Timeout: 15 * time.Minute, - }, - } -} - -// Environment describes a launched test environment -type Environment struct { - App cdk8s.App - CurrentManifest string - root cdk8s.Chart - Charts []ConnectedChart // All connected charts in the - Cfg *Config // The environment specific config - Client *client.K8sClient // Client connecting to the K8s cluster - Fwd *client.Forwarder // Used to forward ports from local machine to the K8s cluster - Artifacts *Artifacts - Chaos *client.Chaos - httpClient *resty.Client - URLs map[string][]string // General URLs of launched resources. Uses '_local' to delineate forwarded ports - ChainlinkNodeDetails []*ChainlinkNodeDetail // ChainlinkNodeDetails has convenient details for connecting to chainlink deployments - err error -} - -// ChainlinkNodeDetail contains details about a chainlink node deployment -type ChainlinkNodeDetail struct { - // ChartName details the name of the Helm chart this node uses, handy for modifying deployment values - // Note: if you are using replicas of the same chart, this will be the same for all nodes - // Use NewDeployment function for Chainlink nodes to make use of this - ChartName string - // PodName is the name of the pod running the chainlink node - PodName string - // LocalIP is the URL to connect to the node from the local machine - LocalIP string - // InternalIP is the URL to connect to the node from inside the K8s cluster - InternalIP string - // DBLocalIP is the URL to connect to the node's database from the local machine - DBLocalIP string -} - -// New creates new environment -func New(cfg *Config) *Environment { - logging.Init() - if cfg == nil { - cfg = &Config{} - } - targetCfg := defaultEnvConfig() - config.MustMerge(targetCfg, cfg) - ns := os.Getenv(config.EnvVarNamespace) - if ns != "" { - cfg.Namespace = ns - } - if cfg.Namespace != "" { - log.Info().Str("Namespace", cfg.Namespace).Msg("Namespace selected") - targetCfg.Namespace = cfg.Namespace - } else { - targetCfg.Namespace = fmt.Sprintf("%s-%s", targetCfg.NamespacePrefix, uuid.NewString()[0:5]) - log.Info().Str("Namespace", targetCfg.Namespace).Msg("Creating new namespace") - } - targetCfg.JobImage = os.Getenv(config.EnvVarJobImage) - targetCfg.detachRunner, _ = strconv.ParseBool(os.Getenv(config.EnvVarDetachRunner)) - targetCfg.InsideK8s, _ = strconv.ParseBool(os.Getenv(config.EnvVarInsideK8s)) - - c, err := client.NewK8sClient() - if err != nil { - return &Environment{err: err} - } - e := &Environment{ - URLs: make(map[string][]string), - Charts: make([]ConnectedChart, 0), - Client: c, - Cfg: targetCfg, - Fwd: client.NewForwarder(c, targetCfg.KeepConnection), - } - arts, err := NewArtifacts(e.Client, e.Cfg.Namespace) - if err != nil { - log.Error().Err(err).Msg("failed to create artifacts client") - return &Environment{err: err} - } - e.Artifacts = arts - - config.JSIIGlobalMu.Lock() - defer config.JSIIGlobalMu.Unlock() - if err := e.initApp(); err != nil { - log.Error().Err(err).Msg("failed to apply the initial manifest to create the namespace") - return &Environment{err: err} - } - e.Chaos = client.NewChaos(c, e.Cfg.Namespace) - - // setup test cleanup if this is using a remote runner - // and not in detached mode - // and not using an existing environment - if targetCfg.JobImage != "" && !targetCfg.detachRunner && !targetCfg.SkipManifestUpdate { - targetCfg.fundReturnFailed = false - if targetCfg.Test != nil { - targetCfg.Test.Cleanup(func() { - err := e.Shutdown() - require.NoError(targetCfg.Test, err) - }) - } - } - return e -} - -var requiredChainLinkNsLabels = []string{"chain.link/team", "chain.link/cost-center", "chain.link/product"} -var requiredChainLinkWorkloadAndPodLabels = append([]string{}, append(requiredChainLinkNsLabels, "chain.link/component")...) - -// validateRequiredChainLinkLabels validates whether the namespace, workloads and pods have the required chain.link labels -// and returns an error with a list of missing labels if any -func (m *Environment) validateRequiredChainLinkLabels() error { - if m.root.Labels() == nil { - return fmt.Errorf("namespace labels are nil, but it should contain at least '%s' labels. Please add them to your environment config under 'Labels' key", strings.Join(requiredChainLinkNsLabels, ", ")) - } - - var missingNsLabels []string - for _, l := range requiredChainLinkNsLabels { - if _, ok := (*m.root.Labels())[l]; !ok { - missingNsLabels = append(missingNsLabels, l) - } - } - - children := m.root.Node().Children() - // map[workflow name][missing labels] - missingWorkloadLabels := make(map[string][]string) - // map[workflow name][missing labels] - missingPodLabels := make(map[string][]string) - - if children == nil { - return nil - } - - var podHasLabel = func(labelName string, podLabels map[string]string) bool { - if len(podLabels) == 0 { - return false - } - for label, _ := range podLabels { - if label == labelName { - return true - } - } - - return false - } - - for _, child := range *children { - // most of our workloads are Helm charts - if h, ok := child.(cdk8s.Helm); ok { - for _, ao := range *h.ApiObjects() { - kind := *ao.Kind() - chartName := *ao.Name() - // map[label]value - var podLabels map[string]string - nodeMightHavePods := mightHavePods(kind) - shouldHavePodLabels := false - if nodeMightHavePods && hasPods(kind, *ao.Chart().ToJson()) { - shouldHavePodLabels = true - podLabels = getJsonPodLabels(kind, *ao.Chart().ToJson()) - } - for _, requiredLabel := range requiredChainLinkWorkloadAndPodLabels { - maybeLabel := ao.Metadata().GetLabel(&requiredLabel) - if maybeLabel == nil { - missingWorkloadLabels[chartName] = append(missingWorkloadLabels[chartName], requiredLabel) - } - if shouldHavePodLabels { - labelFound := podHasLabel(requiredLabel, podLabels) - if !labelFound { - missingPodLabels[chartName] = append(missingPodLabels[chartName], requiredLabel) - } - } - } - } - } - // but legacy runners have no Helm charts, but are programmatically defined as KubeJobs - if j, ok := child.(k8s.KubeJob); ok { - // we have already checked the Namespace - if j.Kind() == nil || *j.Kind() == "Namespace" { - continue - } - - kind := *j.Kind() - name := *j.Name() - - var podLabels map[string]string - nodeMightHavePods := mightHavePods(kind) - shouldHavePodLabels := false - if nodeMightHavePods && hasPods(kind, []interface{}{j.ToJson()}) { - shouldHavePodLabels = true - podLabels = getJsonPodLabels(kind, []interface{}{j.ToJson()}) - } - - for _, requiredLabel := range requiredChainLinkWorkloadAndPodLabels { - maybeLabel := j.Metadata().GetLabel(&requiredLabel) - if maybeLabel == nil { - missingWorkloadLabels[name] = append(missingWorkloadLabels[name], requiredLabel) - } - if shouldHavePodLabels { - labelFound := podHasLabel(requiredLabel, podLabels) - if !labelFound { - missingPodLabels[name] = append(missingPodLabels[name], requiredLabel) - } - } - } - } - } - - if len(missingWorkloadLabels) > 0 { - sb := strings.Builder{} - sb.WriteString("missing required labels for workloads:\n") - for chart, missingLabels := range missingWorkloadLabels { - for _, label := range missingLabels { - sb.WriteString(fmt.Sprintf("\t'%s': '%s'\n", chart, label)) - } - } - sb.WriteString("Please add them to your environment configuration under 'WorkloadLabels' key. And check whether every chart has 'chain.link/component' label defined.") - return errors.New(sb.String()) - } - - if len(missingPodLabels) > 0 { - sb := strings.Builder{} - sb.WriteString("missing required labels for pods:\n") - for chart, missingLabels := range missingPodLabels { - for _, label := range missingLabels { - sb.WriteString(fmt.Sprintf("\t'%s': '%s'\n", chart, label)) - } - } - sb.WriteString("Please add them to your environment configuration under 'WorkloadLabels' key. And check whether every pod in the chart has 'chain.link/component' label defined.") - return errors.New(sb.String()) - } - - return nil -} - -func (m *Environment) initApp() error { - var err error - m.App = cdk8s.NewApp(&cdk8s.AppProps{ - YamlOutputType: cdk8s.YamlOutputType_FILE_PER_APP, - }) - m.Cfg.Labels = append(m.Cfg.Labels, "app.kubernetes.io/managed-by=cdk8s") - owner := os.Getenv(config.EnvVarUser) - if owner == "" { - return fmt.Errorf("missing owner environment variable, please set %s to your name or if you are seeing this in CI please set it to ${{ github.actor }}", config.EnvVarUser) - } - m.Cfg.Labels = append(m.Cfg.Labels, fmt.Sprintf("owner=%s", owner)) - - if os.Getenv(config.EnvVarCLCommitSha) != "" { - m.Cfg.Labels = append(m.Cfg.Labels, fmt.Sprintf("commit=%s", os.Getenv(config.EnvVarCLCommitSha))) - } - testTrigger := os.Getenv(config.EnvVarTestTrigger) - if testTrigger == "" { - testTrigger = "manual" - } - m.Cfg.Labels = append(m.Cfg.Labels, fmt.Sprintf("triggered-by=%s", testTrigger)) - - if tolerationRole := os.Getenv(config.EnvVarToleration); tolerationRole != "" { - m.Cfg.Tolerations = []map[string]string{{ - "key": "node-role", - "operator": "Equal", - "value": tolerationRole, - "effect": "NoSchedule", - }} - } - - if selectorRole := os.Getenv(config.EnvVarNodeSelector); selectorRole != "" { - m.Cfg.NodeSelector = map[string]string{ - "node-role": selectorRole, - } - } - - m.Cfg.Labels = append(m.Cfg.Labels, fmt.Sprintf("%s=%s", pkg.TTLLabelKey, *a.ShortDur(m.Cfg.TTL))) - nsLabels, err := a.ConvertLabels(m.Cfg.Labels) - if err != nil { - return err - } - - m.root = cdk8s.NewChart(m.App, ptr.Ptr(fmt.Sprintf("root-chart-%s", m.Cfg.Namespace)), &cdk8s.ChartProps{ - Labels: nsLabels, - Namespace: ptr.Ptr(m.Cfg.Namespace), - }) - - k8s.NewKubeNamespace(m.root, ptr.Ptr("namespace"), &k8s.KubeNamespaceProps{ - Metadata: &k8s.ObjectMeta{ - Name: ptr.Ptr(m.Cfg.Namespace), - Labels: nsLabels, - Annotations: &defaultNamespaceAnnotations, - }, - }) - m.CurrentManifest = *m.App.SynthYaml() - // loop retry applying the initial manifest with the namespace and other basics - ctx, cancel := context.WithTimeout(testcontext.Get(m.Cfg.Test), m.Cfg.ReadyCheckData.Timeout) - defer cancel() - startTime := time.Now() - deadline, _ := ctx.Deadline() - for { - err = m.Client.Apply(ctx, m.CurrentManifest, m.Cfg.Namespace, true) - if err == nil || ctx.Err() != nil { - break - } - elapsed := time.Since(startTime) - remaining := time.Until(deadline) - log.Debug().Err(err).Msgf("Failed to apply initial manifest, will continue to retry. Time elapsed: %s, Time until timeout %s\n", elapsed, remaining) - time.Sleep(5 * time.Second) - } - if errors.Is(ctx.Err(), context.DeadlineExceeded) { - return fmt.Errorf("failed to apply manifest within %s", m.Cfg.ReadyCheckData.Timeout) - } - if m.Cfg.PodLabels == nil { - m.Cfg.PodLabels = map[string]string{} - } - m.Cfg.PodLabels[pkg.NamespaceLabelKey] = m.Cfg.Namespace - return err -} - -// AddChart adds a chart to the deployment -func (m *Environment) AddChart(f func(root cdk8s.Chart) ConnectedChart) *Environment { - if m.err != nil { - return m - } - config.JSIIGlobalMu.Lock() - defer config.JSIIGlobalMu.Unlock() - m.Charts = append(m.Charts, f(m.root)) - return m -} - -func (m *Environment) removeChart(name string) error { - chartIndex, _, err := m.findChart(name) - if err != nil { - return err - } - m.Charts = append(m.Charts[:chartIndex], m.Charts[chartIndex+1:]...) - m.root.Node().TryRemoveChild(ptr.Ptr(name)) - return nil -} - -// findChart finds a chart by name, returning the index of it in the Charts slice, and the chart itself -func (m *Environment) findChart(name string) (index int, chart ConnectedChart, err error) { - for i, c := range m.Charts { - if c.GetName() == name { - return i, c, nil - } - } - return -1, nil, fmt.Errorf("chart %s not found", name) -} - -// ReplaceHelm entirely replaces an existing helm chart with a new one -// Note: you need to call Run() after this to apply the changes. If you're modifying ConfigMap values, you'll probably -// need to use RollOutStatefulSets to apply the changes to the pods. https://stackoverflow.com/questions/57356521/rollingupdate-for-stateful-set-doesnt-restart-pods-and-changes-from-updated-con -func (m *Environment) ReplaceHelm(name string, chart ConnectedChart) (*Environment, error) { - if m.err != nil { - return nil, m.err - } - config.JSIIGlobalMu.Lock() - defer config.JSIIGlobalMu.Unlock() - if err := m.removeChart(name); err != nil { - return nil, err - } - if m.Cfg.JobImage != "" || !chart.IsDeploymentNeeded() { - return m, fmt.Errorf("cannot modify helm chart '%s' that does not need deployment, it may be in a remote runner or detached mode", name) - } - log.Trace(). - Str("Chart", chart.GetName()). - Str("Path", chart.GetPath()). - Interface("Props", chart.GetProps()). - Interface("Values", chart.GetValues()). - Msg("Chart deployment values") - h := cdk8s.NewHelm(m.root, ptr.Ptr(chart.GetName()), &cdk8s.HelmProps{ - Chart: ptr.Ptr(chart.GetPath()), - HelmFlags: &[]*string{ - ptr.Ptr("--namespace"), - ptr.Ptr(m.Cfg.Namespace), - }, - ReleaseName: ptr.Ptr(chart.GetName()), - Values: chart.GetValues(), - }) - - workloadLabels, err := getComponentLabels(m.Cfg.WorkloadLabels, chart.GetLabels()) - if err != nil { - m.err = err - return nil, err - } - - podLabels, err := getComponentLabels(m.Cfg.PodLabels, chart.GetLabels()) - if err != nil { - m.err = err - return nil, err - } - - addRequiredChainLinkLabelsToWorkloads(h, workloadLabels) - addDefaultPodAnnotationsAndLabels(h, markNotSafeToEvict(m.Cfg.PreventPodEviction, nil), podLabels) - m.Charts = append(m.Charts, chart) - return m, nil -} - -func addDefaultPodAnnotationsAndLabels(h cdk8s.Helm, annotations, labels map[string]string) { - annotationsCopy := map[string]string{} - for k, v := range annotations { - annotationsCopy[k] = v - } - for _, ao := range *h.ApiObjects() { - if ao.Kind() == nil { - continue - } - kind := *ao.Kind() - if mightHavePods(kind) { - // we aren't guaranteed to have annotations in existence so we have to dig down to see if they exist - // and add any to our current list we want to add - aj := *ao.Chart().ToJson() - // loop over the json array until we get the expected kind and look for existing annotations - for _, dep := range aj { - l := fmt.Sprint(dep) - if !strings.Contains(l, fmt.Sprintf("kind:%s", kind)) { - continue - } - depM := dep.(map[string]interface{}) - spec, ok := depM["spec"].(map[string]interface{}) - if !ok { - continue - } - template, ok := spec["template"].(map[string]interface{}) - if !ok { - continue - } - metadata, ok := template["metadata"].(map[string]interface{}) - if !ok { - continue - } - annot, ok := metadata["annotations"].(map[string]interface{}) - if !ok { - continue - } - for k, v := range annot { - annotationsCopy[k] = v.(string) - } - } - annotationPath := "/spec/template/metadata/annotations" - if strings.EqualFold("cronjob", kind) { - annotationPath = "/spec/jobTemplate/spec/template/metadata/annotations" - } - ao.AddJsonPatch(cdk8s.JsonPatch_Add(ptr.Ptr(annotationPath), annotationsCopy)) - - // loop over the labels and apply them to both the labels and selectors - // these should in theory always have at least one label/selector combo in existence so we don't - // have to do the existence check like we do for the annotations - for k, v := range labels { - // Escape the keys according to JSON Pointer syntax in RFC 6901 - escapedKey := strings.ReplaceAll(strings.ReplaceAll(k, "~", "~0"), "/", "~1") - ao.AddJsonPatch(cdk8s.JsonPatch_Add(ptr.Ptr(fmt.Sprintf("/spec/template/metadata/labels/%s", escapedKey)), v)) - // CronJob doesn't have a selector, so we don't need to add it - if !strings.EqualFold("cronjob", kind) { - ao.AddJsonPatch(cdk8s.JsonPatch_Add(ptr.Ptr(fmt.Sprintf("/spec/selector/matchLabels/%s", escapedKey)), v)) - } - } - } - } -} - -func addRequiredChainLinkLabelsToWorkloads(h cdk8s.Helm, labels map[string]string) { - for _, ao := range *h.ApiObjects() { - for k, v := range labels { - ao.Metadata().AddLabel(&k, &v) - } - } -} - -// UpdateHelm update a helm chart with new values. The pod will launch with an `updated=true` label if it's a Chainlink node. -// Note: If you're modifying ConfigMap values, you'll probably need to use RollOutStatefulSets to apply the changes to the pods. -// https://stackoverflow.com/questions/57356521/rollingupdate-for-stateful-set-doesnt-restart-pods-and-changes-from-updated-con -func (m *Environment) UpdateHelm(name string, values map[string]any) (*Environment, error) { - if m.err != nil { - return nil, m.err - } - _, chart, err := m.findChart(name) - if err != nil { - return nil, err - } - if _, labelsExist := values["labels"]; !labelsExist { - values["labels"] = make(map[string]*string) - } - values["labels"].(map[string]*string)["updated"] = ptr.Ptr("true") - if err = mergo.Merge(chart.GetValues(), values, mergo.WithOverride); err != nil { - return nil, err - } - return m.ReplaceHelm(name, chart) -} - -// Charts adds multiple helm charts to the testing environment -func (m *Environment) AddHelmCharts(charts []ConnectedChart) *Environment { - if m.err != nil { - return m - } - for _, c := range charts { - m.AddHelm(c) - } - return m -} - -// AddHelm adds a helm chart to the testing environment -func (m *Environment) AddHelm(chart ConnectedChart) *Environment { - if m.err != nil { - return m - } - if m.Cfg.JobImage != "" || !chart.IsDeploymentNeeded() { - return m - } - config.JSIIGlobalMu.Lock() - defer config.JSIIGlobalMu.Unlock() - - values := &map[string]any{ - "tolerations": m.Cfg.Tolerations, - "nodeSelector": m.Cfg.NodeSelector, - } - config.MustMerge(values, chart.GetValues()) - log.Trace(). - Str("Chart", chart.GetName()). - Str("Path", chart.GetPath()). - Interface("Props", chart.GetProps()). - Interface("Values", values). - Msg("Chart deployment values") - helmFlags := []*string{ - ptr.Ptr("--namespace"), - ptr.Ptr(m.Cfg.Namespace), - ptr.Ptr("--skip-tests"), - } - if chart.GetVersion() != "" { - helmFlags = append(helmFlags, ptr.Ptr("--version"), ptr.Ptr(chart.GetVersion())) - } - chartPath, err := m.PullOCIChart(chart) - if err != nil { - m.err = err - return m - } - h := cdk8s.NewHelm(m.root, ptr.Ptr(chart.GetName()), &cdk8s.HelmProps{ - Chart: ptr.Ptr(chartPath), - HelmFlags: &helmFlags, - ReleaseName: ptr.Ptr(chart.GetName()), - Values: values, - }) - - workloadLabels, err := getComponentLabels(m.Cfg.WorkloadLabels, chart.GetLabels()) - if err != nil { - m.err = err - return m - } - - podLabels, err := getComponentLabels(m.Cfg.PodLabels, chart.GetLabels()) - if err != nil { - m.err = err - return m - } - addRequiredChainLinkLabelsToWorkloads(h, workloadLabels) - addDefaultPodAnnotationsAndLabels(h, markNotSafeToEvict(m.Cfg.PreventPodEviction, nil), podLabels) - m.Charts = append(m.Charts, chart) - return m -} - -func getComponentLabels(podLabels, chartLabels map[string]string) (map[string]string, error) { - componentLabels := make(map[string]string) - err := mergo.Merge(&componentLabels, podLabels, mergo.WithOverride) - if err != nil { - return nil, err - } - err = mergo.Merge(&componentLabels, chartLabels, mergo.WithOverride) - if err != nil { - return nil, err - } - - return componentLabels, nil -} - -// PullOCIChart handles working with OCI format repositories -// https://helm.sh/docs/topics/registries/ -// API is not compatible between helm repos and OCI repos, so we download and untar the chart -func (m *Environment) PullOCIChart(chart ConnectedChart) (string, error) { - if !strings.HasPrefix(chart.GetPath(), "oci") { - return chart.GetPath(), nil - } - cp := strings.Split(chart.GetPath(), "/") - if len(cp) != 5 { - return "", fmt.Errorf(ErrInvalidOCI, chart.GetPath()) - } - sp := strings.Split(chart.GetPath(), ":") - - var cmd string - var chartName string - chartName = cp[len(cp)-1] - chartDir := uuid.NewString() - switch len(sp) { - case 2: - cmd = fmt.Sprintf("helm pull %s --untar --untardir %s", chart.GetPath(), chartDir) - case 3: - chartName = strings.Split(chartName, ":")[0] - cmd = fmt.Sprintf("helm pull %s --version %s --untar --untardir %s", fmt.Sprintf("%s:%s", sp[0], sp[1]), sp[2], chartDir) - default: - return "", fmt.Errorf(ErrInvalidOCI, chart.GetPath()) - } - log.Info().Str("CMD", cmd).Msg("Running helm cmd") - if err := client.ExecCmd(cmd); err != nil { - return "", fmt.Errorf(ErrOCIPull, chart.GetPath()) - } - localChartPath := fmt.Sprintf("%s/%s/", chartDir, chartName) - log.Info().Str("Path", localChartPath).Msg("Local chart path") - return localChartPath, nil -} - -// PrintExportData prints export data -func (m *Environment) PrintExportData() error { - m.URLs = make(map[string][]string) - for _, c := range m.Charts { - err := c.ExportData(m) - if err != nil { - return err - } - } - log.Debug().Interface("URLs", m.URLs).Msg("Connection URLs") - return nil -} - -// DumpLogs dumps all logs into a file -func (m *Environment) DumpLogs(path string) error { - arts, err := NewArtifacts(m.Client, m.Cfg.Namespace) - if err != nil { - return err - } - if path == "" { - path = fmt.Sprintf("logs/%s-%d", m.Cfg.Namespace, time.Now().Unix()) - } - return arts.DumpTestResult(path, "chainlink") -} - -// ResourcesSummary returns resources summary for selected pods as a map, used in reports -func (m *Environment) ResourcesSummary(selector string) (map[string]map[string]string, error) { - pl, err := m.Client.ListPods(m.Cfg.Namespace, selector) - if err != nil { - return nil, err - } - if len(pl.Items) == 0 { - return nil, fmt.Errorf("no pods found for selector: %s", selector) - } - resources := make(map[string]map[string]string) - for _, p := range pl.Items { - for _, c := range p.Spec.Containers { - if resources[c.Name] == nil { - resources[c.Name] = make(map[string]string) - } - cpuRes := c.Resources.Requests["cpu"] - resources[c.Name]["cpu"] = cpuRes.String() - memRes := c.Resources.Requests["memory"] - resources[c.Name]["memory"] = memRes.String() - } - } - return resources, nil -} - -// ClearCharts recreates cdk8s app -func (m *Environment) ClearCharts() error { - m.Charts = make([]ConnectedChart, 0) - if err := m.initApp(); err != nil { - log.Error().Err(err).Msg("failed to apply the initial manifest to create the namespace") - return err - } - return nil -} - -func (m *Environment) Manifest() string { - return m.CurrentManifest -} - -// Update current manifest based on the cdk8s app state -func (m *Environment) UpdateManifest() { - config.JSIIGlobalMu.Lock() - m.CurrentManifest = *m.App.SynthYaml() - config.JSIIGlobalMu.Unlock() -} - -// RunCustomReadyConditions Runs the environment with custom ready conditions for a supplied pod count -func (m *Environment) RunCustomReadyConditions(customCheck *client.ReadyCheckData, podCount int) error { - if m.err != nil { - return m.err - } - if m.Cfg.jobDeployed { - return nil - } - if m.Cfg.JobImage != "" { - if m.Cfg.Test == nil { - return fmt.Errorf("Test must be configured in the environment when using the remote runner") - } - remoteRunnerLabels := map[string]*string{pkg.NamespaceLabelKey: ptr.Ptr(m.Cfg.Namespace)} - for l, v := range m.Cfg.WorkloadLabels { - remoteRunnerLabels[l] = ptr.Ptr(v) - } - // if no runner name is specified use constant - if m.Cfg.RunnerName == "" { - m.Cfg.RunnerName = REMOTE_RUNNER_NAME - } - m.AddChart(NewRunner(&Props{ - BaseName: m.Cfg.RunnerName, - ReportPath: m.Cfg.ReportPath, - TargetNamespace: m.Cfg.Namespace, - Labels: &remoteRunnerLabels, - Image: m.Cfg.JobImage, - TestName: m.Cfg.Test.Name(), - SkipManifestUpdate: m.Cfg.SkipManifestUpdate, - PreventPodEviction: m.Cfg.PreventPodEviction, - })) - // add a pod to access reports generated by remote-runner, even after remote-runner's job execution completion - if m.Cfg.ReportPath != "" { - m.AddChart(DataFromRunner(&Props{ - BaseName: m.Cfg.RunnerName, - ReportPath: m.Cfg.ReportPath, - TargetNamespace: m.Cfg.Namespace, - Labels: &remoteRunnerLabels, - Image: m.Cfg.JobImage, - TestName: m.Cfg.Test.Name(), - SkipManifestUpdate: m.Cfg.SkipManifestUpdate, - PreventPodEviction: m.Cfg.PreventPodEviction, - })) - } - } - m.UpdateManifest() - m.ChainlinkNodeDetails = []*ChainlinkNodeDetail{} // Resets potentially old details if re-deploying - if m.Cfg.DryRun { - log.Info().Msg("Dry-run mode, manifest synthesized and saved as tmp-manifest.yaml") - return nil - } - manifestUpdate := os.Getenv(config.EnvVarSkipManifestUpdate) - if manifestUpdate != "" { - mu, err := strconv.ParseBool(manifestUpdate) - if err != nil { - return fmt.Errorf("manifest update should be bool: true, false") - } - m.Cfg.SkipManifestUpdate = mu - } - log.Debug().Bool("ManifestUpdate", m.Cfg.SkipManifestUpdate).Msg("Update mode") - - if !m.Cfg.SkipRequiredChainLinkLabelsValidation { - // make sure all required chain.link labels are present in the final manifest - if err := m.validateRequiredChainLinkLabels(); err != nil { - return err - } - } - - if !m.Cfg.SkipManifestUpdate || m.Cfg.JobImage != "" { - if err := m.DeployCustomReadyConditions(customCheck, podCount); err != nil { - log.Error().Err(err).Msg("Error deploying environment") - _ = m.Shutdown() - return err - } - } - if m.Cfg.JobImage != "" { - log.Info().Msg("Waiting for remote runner to complete") - // Do not wait for the job to complete if we are running something like a soak test in the remote runner - if m.Cfg.detachRunner { - return nil - } - if err := m.Client.WaitForJob(m.Cfg.Namespace, m.Cfg.RunnerName, func(message string) { - if m.Cfg.JobLogFunction != nil { - m.Cfg.JobLogFunction(m, message) - } else { - DefaultJobLogFunction(m, message) - } - }); err != nil { - return err - } - if m.Cfg.fundReturnFailed { - return fmt.Errorf("failed to return funds in remote runner") - } - m.Cfg.jobDeployed = true - } else { - if err := m.Fwd.Connect(m.Cfg.Namespace, "", m.Cfg.InsideK8s); err != nil { - return err - } - log.Debug().Interface("Ports", m.Fwd.Info).Msg("Forwarded ports") - m.Fwd.PrintLocalPorts() - if err := m.PrintExportData(); err != nil { - return err - } - arts, err := NewArtifacts(m.Client, m.Cfg.Namespace) - if err != nil { - log.Error().Err(err).Msg("failed to create artifacts client") - return err - } - m.Artifacts = arts - if len(m.URLs["goc"]) != 0 { - m.httpClient = resty.New().SetBaseURL(m.URLs["goc"][0]) - } - if m.Cfg.KeepConnection { - log.Info().Msg("Keeping forwarder connections, press Ctrl+C to interrupt") - if m.Cfg.RemoveOnInterrupt { - log.Warn().Msg("Environment will be removed on interrupt") - } - ch := make(chan os.Signal, 1) - signal.Notify(ch, os.Interrupt, syscall.SIGTERM) - <-ch - log.Warn().Msg("Interrupted") - if m.Cfg.RemoveOnInterrupt { - return m.Client.RemoveNamespace(m.Cfg.Namespace) - } - } - } - return nil -} - -// RunUpdated runs the environment and checks for pods with `updated=true` label -func (m *Environment) RunUpdated(podCount int) error { - if m.err != nil { - return m.err - } - conds := &client.ReadyCheckData{ - ReadinessProbeCheckSelector: "updated=true", - Timeout: 10 * time.Minute, - } - return m.RunCustomReadyConditions(conds, podCount) -} - -// Run deploys or connects to already created environment -func (m *Environment) Run() error { - if m.err != nil { - return m.err - } - return m.RunCustomReadyConditions(nil, 0) -} - -func (m *Environment) enumerateApps() error { - apps, err := m.Client.UniqueLabels(m.Cfg.Namespace, client.AppLabel) - if err != nil { - return err - } - for _, app := range apps { - if err := m.Client.EnumerateInstances(m.Cfg.Namespace, fmt.Sprintf("app=%s", app)); err != nil { - return err - } - } - return nil -} - -// DeployCustomReadyConditions deploy current manifest with added custom readiness checks -func (m *Environment) DeployCustomReadyConditions(customCheck *client.ReadyCheckData, customPodCount int) error { - if m.err != nil { - return m.err - } - log.Info().Str("Namespace", m.Cfg.Namespace).Msg("Deploying namespace") - - if m.Cfg.DryRun { - return m.Client.DryRun(m.CurrentManifest) - } - ctx, cancel := context.WithTimeout(testcontext.Get(m.Cfg.Test), m.Cfg.ReadyCheckData.Timeout) - defer cancel() - err := m.Client.Apply(ctx, m.CurrentManifest, m.Cfg.Namespace, true) - if errors.Is(ctx.Err(), context.DeadlineExceeded) { - return fmt.Errorf("timeout waiting for environment to be ready") - } - if err != nil { - return err - } - if int64(m.Cfg.UpdateWaitInterval) != 0 { - time.Sleep(m.Cfg.UpdateWaitInterval) - } - - expectedPodCount := m.findPodCountInDeploymentManifest() - - if err := m.Client.WaitPodsReady(m.Cfg.Namespace, m.Cfg.ReadyCheckData, expectedPodCount); err != nil { - return err - } - if customCheck != nil { - if err := m.Client.WaitPodsReady(m.Cfg.Namespace, customCheck, customPodCount); err != nil { - return err - } - } - return m.enumerateApps() -} - -// Deploy deploys current manifest and check logs for readiness -func (m *Environment) Deploy() error { - return m.DeployCustomReadyConditions(nil, 0) -} - -// RolloutStatefulSets applies "rollout statefulset" to all existing statefulsets in our namespace -func (m *Environment) RolloutStatefulSets() error { - if m.err != nil { - return m.err - } - ctx, cancel := context.WithTimeout(testcontext.Get(m.Cfg.Test), m.Cfg.ReadyCheckData.Timeout) - defer cancel() - err := m.Client.RolloutStatefulSets(ctx, m.Cfg.Namespace) - if errors.Is(ctx.Err(), context.DeadlineExceeded) { - return fmt.Errorf("timeout waiting for rollout statefulset to complete") - } - return err -} - -// CopyFromPod lists pods with given selector, it copies files from local to destPath at pods filtered by given selector -func (m *Environment) CopyFromPod(selector, containerName, srcPath, destPath string) error { - pl, err := m.Client.ListPods(m.Cfg.Namespace, selector) - if err != nil { - return err - } - if len(pl.Items) == 0 { - return fmt.Errorf("no pods found for selector: %s", selector) - } - for _, p := range pl.Items { - err := m.Client.CopyFromPod(context.Background(), m.Cfg.Namespace, p.Name, containerName, srcPath, destPath) - if err != nil { - return fmt.Errorf("%w error copying from %s:%s to destination path %s", err, p.Name, srcPath, destPath) - } - } - return nil -} - -// CopyToPod lists pods with given selector, it copies files from srcPath at pods filtered by given selector to -// local destPath -func (m *Environment) CopyToPod(selector, containerName, srcPath, destPath string) error { - pl, err := m.Client.ListPods(m.Cfg.Namespace, selector) - if err != nil { - return err - } - if len(pl.Items) == 0 { - return fmt.Errorf("no pods found for selector: %s", selector) - } - for _, p := range pl.Items { - destPath = fmt.Sprintf("%s/%s:/%s", m.Cfg.Namespace, p.Name, destPath) - _, _, _, err := m.Client.CopyToPod(m.Cfg.Namespace, srcPath, destPath, containerName) - if err != nil { - return fmt.Errorf("%w error copying from %s to destination path %s", err, srcPath, destPath) - } - } - return nil -} - -// RolloutRestartBySelector applies "rollout restart" to the selected resources -func (m *Environment) RolloutRestartBySelector(resource string, selector string) error { - if m.err != nil { - return m.err - } - ctx, cancel := context.WithTimeout(testcontext.Get(m.Cfg.Test), m.Cfg.ReadyCheckData.Timeout) - defer cancel() - err := m.Client.RolloutRestartBySelector(ctx, m.Cfg.Namespace, resource, selector) - if errors.Is(ctx.Err(), context.DeadlineExceeded) { - return fmt.Errorf("timeout waiting for rollout restart to complete") - } - return err -} - -// findPodsInDeploymentManifest finds all the pods we will be deploying -func (m *Environment) findPodCountInDeploymentManifest() int { - config.JSIIGlobalMu.Lock() - defer config.JSIIGlobalMu.Unlock() - podCount := 0 - charts := m.App.Charts() - for _, chart := range *charts { - json := chart.ToJson() - if json == nil { - continue - } - for _, j := range *json { - m := j.(map[string]any) - // if the kind is a deployment then we want to see if it has replicas to count towards the app count - if _, ok := m["kind"]; !ok { - continue - } - kind := m["kind"].(string) - if kind == "Deployment" || kind == "StatefulSet" { - if _, ok := m["spec"]; !ok { - continue - } - podCount += getReplicaCount(m["spec"].(map[string]any)) - } - } - - } - return podCount -} - -func getReplicaCount(spec map[string]any) int { - if spec == nil { - return 0 - } - if _, ok := spec["selector"]; !ok { - return 0 - } - s := spec["selector"].(map[string]any) - if s == nil { - return 0 - } - if _, ok := s["matchLabels"]; !ok { - return 0 - } - m := s["matchLabels"].(map[string]any) - if m == nil { - return 0 - } - if _, ok := m[client.AppLabel]; !ok { - return 0 - } - l := m[client.AppLabel] - if l == nil { - return 0 - } - - replicaCount := 0 - var replicas any - replicas, ok := spec["replicas"] - if ok { - replicaCount += int(replicas.(float64)) - } else { - replicaCount++ - } - - return replicaCount -} - -type CoverageProfileParams struct { - Force bool `form:"force" json:"force"` - Service []string `form:"service" json:"service"` - Address []string `form:"address" json:"address"` - CoverFilePatterns []string `form:"coverfile" json:"coverfile"` - SkipFilePatterns []string `form:"skipfile" json:"skipfile"` -} - -func (m *Environment) getCoverageList() (map[string]any, error) { - var servicesMap map[string]any - resp, err := m.httpClient.R(). - SetResult(&servicesMap). - Get("v1/cover/list") - if err != nil { - return nil, err - } - if resp.Status() != "200 OK" { - return nil, fmt.Errorf("coverage service list request is not 200") - } - return servicesMap, nil -} - -func (m *Environment) ClearCoverage() error { - servicesMap, err := m.getCoverageList() - if err != nil { - return err - } - for serviceName := range servicesMap { - r, err := m.httpClient.R(). - SetBody(CoverageProfileParams{Service: []string{serviceName}}). - Post("v1/cover/clear") - if err != nil { - return err - } - if r.Status() != "200 OK" { - return fmt.Errorf("coverage service list request is not 200") - } - log.Debug().Str("Service", serviceName).Msg("Coverage cleared") - } - return nil -} - -func (m *Environment) SaveCoverage() error { - if err := MkdirIfNotExists(COVERAGE_DIR); err != nil { - return err - } - servicesMap, err := m.getCoverageList() - if err != nil { - return err - } - log.Debug().Interface("Services", servicesMap).Msg("Services eligible for coverage") - for serviceName := range servicesMap { - r, err := m.httpClient.R(). - SetBody(CoverageProfileParams{Service: []string{serviceName}}). - Post("v1/cover/profile") - if err != nil { - return err - } - if r.Status() != "200 OK" { - return fmt.Errorf("coverage service list request is not 200") - } - log.Debug().Str("Service", serviceName).Msg("Coverage received") - if err := os.WriteFile(fmt.Sprintf("%s/%s.cov", COVERAGE_DIR, serviceName), r.Body(), os.ModePerm); err != nil { - return err - } - } - return nil -} - -// Shutdown environment, remove namespace -func (m *Environment) Shutdown() error { - // don't shutdown if returning of funds failed - if m.Cfg.fundReturnFailed { - return nil - } - - // don't shutdown if this is a test running remotely - if m.Cfg.InsideK8s { - return nil - } - - keepEnvs := os.Getenv(config.EnvVarKeepEnvironments) - if keepEnvs == "" { - keepEnvs = "NEVER" - } - - shouldShutdown := false - switch strings.ToUpper(keepEnvs) { - case "ALWAYS": - return nil - case "ONFAIL": - if m.Cfg.Test != nil { - if !m.Cfg.Test.Failed() { - shouldShutdown = true - } - } - case "NEVER": - shouldShutdown = true - default: - log.Warn().Str("Invalid Keep Value", keepEnvs). - Msg("Invalid 'keep_environments' value, see the KEEP_ENVIRONMENTS env var") - } - - if shouldShutdown { - return m.Client.RemoveNamespace(m.Cfg.Namespace) - } - return nil -} - -// WillUseRemoteRunner determines if we need to start the remote runner -func (m *Environment) WillUseRemoteRunner() bool { - val, _ := os.LookupEnv(config.EnvVarJobImage) - return val != "" && m.Cfg != nil && m.Cfg.Test != nil && m.Cfg.Test.Name() != "" -} - -func DefaultJobLogFunction(e *Environment, message string) { - logChunks := logging.SplitStringIntoChunks(message, 50000) - for _, chunk := range logChunks { - e.Cfg.Test.Log(chunk) - } - if strings.Contains(message, FAILED_FUND_RETURN) { - e.Cfg.fundReturnFailed = true - } - if strings.Contains(message, TEST_FAILED) { - e.Cfg.Test.Fail() - } -} - -// markNotSafeToEvict adds the safe to evict annotation to the provided map if needed -func markNotSafeToEvict(preventPodEviction bool, m map[string]string) map[string]string { - if m == nil { - m = make(map[string]string) - } - if preventPodEviction { - m["karpenter.sh/do-not-evict"] = "true" - m["karpenter.sh/do-not-disrupt"] = "true" - m["cluster-autoscaler.kubernetes.io/safe-to-evict"] = "false" - } - - return m -} - -// GetRequiredChainLinkNamespaceLabels returns the required chain.link namespace labels -// if `CHAINLINK_USER_TEAM` env var is not set it will return an error -func GetRequiredChainLinkNamespaceLabels(product, testType string) ([]string, error) { - var nsLabels []string - createdLabels, err := createRequiredChainLinkLabels(product, testType) - if err != nil { - return nsLabels, err - } - - for k, v := range createdLabels { - nsLabels = append(nsLabels, fmt.Sprintf("%s=%s", k, v)) - } - - return nsLabels, nil -} - -// GetRequiredChainLinkWorkloadAndPodLabels returns the required chain.link workload and pod labels -// if `CHAINLINK_USER_TEAM` env var is not set it will return an error -func GetRequiredChainLinkWorkloadAndPodLabels(product, testType string) (map[string]string, error) { - createdLabels, err := createRequiredChainLinkLabels(product, testType) - if err != nil { - return nil, err - } - - return createdLabels, nil -} - -func createRequiredChainLinkLabels(product, testType string) (map[string]string, error) { - team := os.Getenv(config.EnvVarTeam) - if team == "" { - return nil, fmt.Errorf("missing team environment variable, please set %s to your team name or if you are seeing this in CI please either add a new input with team name or hardcode it if this jobs is only run by a single team", config.EnvVarTeam) - } - - return map[string]string{ - "chain.link/product": product, - "chain.link/team": team, - "chain.link/cost-center": fmt.Sprintf("test-tooling-%s-test", testType), - }, nil -} - -// mightHavePods returns true if the kind of k8s resource might have pods -func mightHavePods(kind string) bool { - switch kind { - // only these objects contain pods in their definition - case "Deployment", "ReplicaSet", "StatefulSet", "Job", "CronJob", "DaemonSet": - return true - } - - return false -} - -// hasPods checks if the json representing k8s resource has any pods -func hasPods(kind string, maybeJson []interface{}) bool { - var hasSpecContainers = func(depMap map[string]interface{}) bool { - spec, ok := depMap["spec"].(map[string]interface{}) - if !ok { - return false - } - containers, ok := spec["containers"].([]interface{}) - if !ok { - return false - } - - return len(containers) > 0 - } - - switch kind { - case "CronJob": - foundPods := false - for _, dep := range maybeJson { - depM := dep.(map[string]interface{}) - spec, ok := depM["spec"].(map[string]interface{}) - if !ok { - continue - } - jobTemplate, ok := spec["jobTemplate"].(map[string]interface{}) - if !ok { - continue - } - spec2, ok := jobTemplate["spec"].(map[string]interface{}) - if !ok { - continue - } - template, ok := spec2["template"].(map[string]interface{}) - if !ok { - continue - } - if hasSpecContainers(template) { - foundPods = true - break - } - } - return foundPods - default: - foundPods := false - for _, dep := range maybeJson { - depM := dep.(map[string]interface{}) - spec, ok := depM["spec"].(map[string]interface{}) - if !ok { - continue - } - template, ok := spec["template"].(map[string]interface{}) - if !ok { - continue - } - if hasSpecContainers(template) { - foundPods = true - break - } - } - return foundPods - } - - return false -} - -// getJsonPodLabels returns the labels for the pods in the json, which represents k8s resource -// it returns pod labels of the first resource with these labels -func getJsonPodLabels(kind string, maybeJson []interface{}) map[string]string { - templateLabels := make(map[string]string) - for _, dep := range maybeJson { - l := fmt.Sprint(dep) - if !strings.Contains(l, fmt.Sprintf("kind:%s", kind)) { - continue - } - depM := dep.(map[string]interface{}) - spec, ok := depM["spec"].(map[string]interface{}) - if !ok { - continue - } - - // CronJob has a different structure for the labels - var specRoot map[string]interface{} - if strings.EqualFold(kind, "CronJob") { - jobTemplate, ok := spec["jobTemplate"].(map[string]interface{}) - if !ok { - continue - } - spec2, ok := jobTemplate["spec"].(map[string]interface{}) - if !ok { - continue - } - specRoot = spec2 - } else { - specRoot = spec - } - - template, ok := specRoot["template"].(map[string]interface{}) - if !ok { - continue - } - metadata, ok := template["metadata"].(map[string]interface{}) - if !ok { - continue - } - labels, ok := metadata["labels"].(map[string]interface{}) - if !ok { - continue - } - - for k, v := range labels { - templateLabels[k] = v.(string) - } - break - } - - return templateLabels -} diff --git a/lib/k8s/environment/runner.go b/lib/k8s/environment/runner.go deleted file mode 100644 index 04d67ffcc..000000000 --- a/lib/k8s/environment/runner.go +++ /dev/null @@ -1,471 +0,0 @@ -package environment - -import ( - "bytes" - "fmt" - "os" - "strconv" - "strings" - - "github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2" - "github.com/rs/zerolog/log" - - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/config" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/imports/k8s" - a "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/alias" - "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/ptr" -) - -const REMOTE_RUNNER_NAME = "remote-test-runner" - -type Chart struct { - Props *Props -} - -func (m Chart) IsDeploymentNeeded() bool { - return true -} - -func (m Chart) GetName() string { - return m.Props.BaseName -} - -func (m Chart) GetProps() interface{} { - return m.Props -} - -func (m Chart) GetPath() string { - return "" -} - -func (m Chart) GetVersion() string { - return "" -} - -func (m Chart) GetValues() *map[string]interface{} { - return nil -} - -func (m Chart) ExportData(e *Environment) error { - return nil -} - -func (m Chart) GetLabels() map[string]string { - if m.GetProps() == nil { - return nil - } - - if props, ok := m.GetProps().(*Props); ok { - if props == nil { - return nil - } - labels := make(map[string]string) - for k, v := range *props.Labels { - if v == nil { - continue - } - labels[k] = *v - } - } - - return nil -} - -func NewRunner(props *Props) func(root cdk8s.Chart) ConnectedChart { - return func(root cdk8s.Chart) ConnectedChart { - labels := *props.Labels - labels["chain.link/component"] = ptr.Ptr("test-runner") - c := &Chart{ - Props: props, - } - // if reportPath is given we create a persistent volume - // so that data generated by remote-runner can be accessed from other pods - // accessing the same pvc volume - if props.ReportPath != "" { - pvcVolume(root, props) - } - kubeSecret(root, props) - role(root, props) - job(root, props) - return c - } -} - -// DataFromRunner - we create this pod to share same persistent volume as remote-runner-node container. This container -// keeps on running and stays alive after the remote-runner-node gets completed, so that -// the calling test can access all files generated by remote runner. -func DataFromRunner(props *Props) func(root cdk8s.Chart) ConnectedChart { - labels := *props.Labels - labels["app"] = ptr.Ptr("runner-data") - labels["chain.link/component"] = ptr.Ptr("test-runner") - return func(root cdk8s.Chart) ConnectedChart { - c := &Chart{ - Props: props, - } - k8s.NewKubeDeployment( - root, - ptr.Ptr(fmt.Sprintf("%s-data", props.BaseName)), - &k8s.KubeDeploymentProps{ - Metadata: &k8s.ObjectMeta{ - Name: ptr.Ptr(fmt.Sprintf("%s-data", props.BaseName)), - Labels: &labels, - }, - Spec: &k8s.DeploymentSpec{ - Selector: &k8s.LabelSelector{ - MatchLabels: &labels, - }, - Template: &k8s.PodTemplateSpec{ - Metadata: &k8s.ObjectMeta{ - Labels: &labels, - }, - Spec: &k8s.PodSpec{ - ServiceAccountName: ptr.Ptr("default"), - // try to schedule the pod on same node as remote runner job - Affinity: &k8s.Affinity{ - PodAffinity: &k8s.PodAffinity{ - RequiredDuringSchedulingIgnoredDuringExecution: &[]*k8s.PodAffinityTerm{ - { - LabelSelector: &k8s.LabelSelector{ - MatchLabels: &map[string]*string{ - "job-name": ptr.Ptr("remote-test-runner"), - }, - }, - TopologyKey: ptr.Ptr("kubernetes.io/hostname"), - }, - }, - }, - }, - Volumes: ptr.Ptr([]*k8s.Volume{ - { - Name: ptr.Ptr("reports"), - PersistentVolumeClaim: ptr.Ptr(k8s.PersistentVolumeClaimVolumeSource{ - ClaimName: ptr.Ptr(fmt.Sprintf("%s-data-pvc", props.BaseName)), - }), - }, - }), - Containers: &[]*k8s.Container{ - { - Name: ptr.Ptr(fmt.Sprintf("%s-data-files", props.BaseName)), - Image: ptr.Ptr("busybox:stable"), - ImagePullPolicy: ptr.Ptr("Always"), - Command: ptr.Ptr([]*string{ptr.Ptr("/bin/sh"), ptr.Ptr("-ec"), ptr.Ptr("while :; do echo '.'; sleep 5 ; done")}), - Ports: ptr.Ptr([]*k8s.ContainerPort{ - { - ContainerPort: ptr.Ptr(float64(80)), - }, - }), - VolumeMounts: &[]*k8s.VolumeMount{ - { - Name: ptr.Ptr("reports"), - MountPath: ptr.Ptr("reports"), - }, - }, - }, - }, - }, - }, - }, - }) - return c - } -} - -type Props struct { - BaseName string - ReportPath string - TargetNamespace string - Labels *map[string]*string - Image string - TestName string - SkipManifestUpdate bool - PreventPodEviction bool -} - -func role(chart cdk8s.Chart, props *Props) { - k8s.NewKubeRole( - chart, - ptr.Ptr(fmt.Sprintf("%s-role", props.BaseName)), - &k8s.KubeRoleProps{ - Metadata: &k8s.ObjectMeta{ - Name: ptr.Ptr(props.BaseName), - Labels: props.Labels, - }, - Rules: &[]*k8s.PolicyRule{ - { - ApiGroups: &[]*string{ - ptr.Ptr(""), // this empty line is needed or k8s get really angry - ptr.Ptr("apps"), - ptr.Ptr("batch"), - ptr.Ptr("core"), - ptr.Ptr("networking.k8s.io"), - ptr.Ptr("storage.k8s.io"), - ptr.Ptr("policy"), - ptr.Ptr("chaos-mesh.org"), - ptr.Ptr("monitoring.coreos.com"), - ptr.Ptr("rbac.authorization.k8s.io"), - }, - Resources: &[]*string{ - ptr.Ptr("*"), - }, - Verbs: &[]*string{ - ptr.Ptr("*"), - }, - }, - }, - }) - k8s.NewKubeRoleBinding( - chart, - ptr.Ptr(fmt.Sprintf("%s-role-binding", props.BaseName)), - &k8s.KubeRoleBindingProps{ - RoleRef: &k8s.RoleRef{ - ApiGroup: ptr.Ptr("rbac.authorization.k8s.io"), - Kind: ptr.Ptr("Role"), - Name: ptr.Ptr("remote-test-runner"), - }, - Metadata: &k8s.ObjectMeta{ - Labels: props.Labels, - }, - Subjects: &[]*k8s.Subject{ - { - Kind: ptr.Ptr("ServiceAccount"), - Name: ptr.Ptr("default"), - Namespace: ptr.Ptr(props.TargetNamespace), - }, - }, - }, - ) -} - -func kubeSecret(chart cdk8s.Chart, props *Props) { - k8s.NewKubeSecret( - chart, - ptr.Ptr("ts-secret"), - &k8s.KubeSecretProps{ - Metadata: &k8s.ObjectMeta{ - Name: ptr.Ptr("ts-secret"), - Labels: props.Labels, - }, - Type: ptr.Ptr("Opaque"), // Typical for storing arbitrary user-defined data - StringData: &map[string]*string{ - ".testsecrets": ptr.Ptr(createTestSecretsDotenvFromEnvVars()), - }, - }, - ) -} - -func job(chart cdk8s.Chart, props *Props) { - defaultRunnerPodAnnotations := markNotSafeToEvict(props.PreventPodEviction, nil) - restartPolicy := "Never" - backOffLimit := float64(0) - if os.Getenv(config.EnvVarDetachRunner) == "true" { // If we're running detached, we're likely running a long-form test - restartPolicy = "OnFailure" - backOffLimit = 100000 // effectively infinite (I hope) - } - volumes := []*k8s.Volume{ - { - Name: ptr.Ptr("persistence"), - EmptyDir: &k8s.EmptyDirVolumeSource{}, - }, - } - // if reportPath is given we create a volume attached to PVC volume claim - if props.ReportPath != "" { - volumes = append(volumes, &k8s.Volume{ - Name: ptr.Ptr("reports"), - PersistentVolumeClaim: ptr.Ptr(k8s.PersistentVolumeClaimVolumeSource{ - ClaimName: ptr.Ptr(fmt.Sprintf("%s-data-pvc", props.BaseName)), - }), - }) - } - volumes = append(volumes, &k8s.Volume{ - Name: ptr.Ptr("ts-volume"), - Secret: &k8s.SecretVolumeSource{ - SecretName: ptr.Ptr("ts-secret"), - }, - }) - k8s.NewKubeJob( - chart, - ptr.Ptr(fmt.Sprintf("%s-job", props.BaseName)), - &k8s.KubeJobProps{ - Metadata: &k8s.ObjectMeta{ - Name: ptr.Ptr(props.BaseName), - Labels: props.Labels, - }, - Spec: &k8s.JobSpec{ - Template: &k8s.PodTemplateSpec{ - Metadata: &k8s.ObjectMeta{ - Labels: props.Labels, - Annotations: a.ConvertAnnotations(defaultRunnerPodAnnotations), - }, - Spec: &k8s.PodSpec{ - ServiceAccountName: ptr.Ptr("default"), - Containers: container(props), - RestartPolicy: ptr.Ptr(restartPolicy), - Volumes: &volumes, - }, - }, - ActiveDeadlineSeconds: nil, - BackoffLimit: ptr.Ptr(backOffLimit), - }, - }) -} - -func container(props *Props) *[]*k8s.Container { - cpu := os.Getenv(config.EnvVarRemoteRunnerCpu) - if cpu == "" { - cpu = "1000m" - } - mem := os.Getenv(config.EnvVarRemoteRunnerMem) - if mem == "" { - mem = "1024Mi" - } - volumeMounts := []*k8s.VolumeMount{ - { - Name: ptr.Ptr("persistence"), - MountPath: ptr.Ptr("/persistence"), - }, - } - // if reportPath is given we create a volume mount attached to PVC volume claim - if props.ReportPath != "" { - volumeMounts = append(volumeMounts, &k8s.VolumeMount{ - Name: ptr.Ptr("reports"), - MountPath: ptr.Ptr(fmt.Sprintf("/go/testdir/integration-tests/%s", props.ReportPath)), - SubPath: ptr.Ptr(props.ReportPath), - }) - } - // Mount test secrets dotenv file - volumeMounts = append(volumeMounts, &k8s.VolumeMount{ - Name: ptr.Ptr("ts-volume"), - MountPath: ptr.Ptr("/etc/e2etests"), - }) - return ptr.Ptr([]*k8s.Container{ - { - Name: ptr.Ptr(fmt.Sprintf("%s-node", props.BaseName)), - Image: ptr.Ptr(props.Image), - ImagePullPolicy: ptr.Ptr("Always"), - Env: jobEnvVars(props), - Resources: a.ContainerResources(cpu, mem, cpu, mem), - VolumeMounts: &volumeMounts, - }, - }) -} - -func pvcVolume(chart cdk8s.Chart, props *Props) { - labels := make(map[string]*string) - for k, v := range *props.Labels { - labels[k] = v - } - labels["type"] = ptr.Ptr("local") - k8s.NewKubePersistentVolume( - chart, - ptr.Ptr(fmt.Sprintf("%s-data-pv-volume", props.BaseName)), - &k8s.KubePersistentVolumeProps{ - Metadata: &k8s.ObjectMeta{ - Name: ptr.Ptr(fmt.Sprintf("%s-data-pv-volume", props.BaseName)), - Labels: &labels, - }, - Spec: &k8s.PersistentVolumeSpec{ - AccessModes: ptr.Ptr([]*string{ptr.Ptr("ReadWriteOnce")}), - Capacity: &map[string]k8s.Quantity{ - "storage": k8s.Quantity_FromString(ptr.Ptr("256Mi")), - }, - HostPath: &k8s.HostPathVolumeSource{ - Path: ptr.Ptr("/mnt/data"), - }, - PersistentVolumeReclaimPolicy: ptr.Ptr("Delete"), - }, - }, - ) - k8s.NewKubePersistentVolumeClaim( - chart, - ptr.Ptr(fmt.Sprintf("%s-data-pvc", props.BaseName)), - &k8s.KubePersistentVolumeClaimProps{ - Metadata: &k8s.ObjectMeta{ - Name: ptr.Ptr(fmt.Sprintf("%s-data-pvc", props.BaseName)), - Labels: props.Labels, - }, - Spec: &k8s.PersistentVolumeClaimSpec{ - AccessModes: ptr.Ptr([]*string{ptr.Ptr("ReadWriteOnce")}), - VolumeMode: ptr.Ptr("Filesystem"), - Resources: &k8s.ResourceRequirements{ - Requests: &map[string]k8s.Quantity{ - "storage": k8s.Quantity_FromString(ptr.Ptr("256Mi")), - }, - }, - }, - }) -} - -func createTestSecretsDotenvFromEnvVars() string { - var buffer bytes.Buffer - - for _, pair := range os.Environ() { - split := strings.SplitN(pair, "=", 2) // Split the pair into key and value - if len(split) != 2 { - continue // Skip any invalid entries - } - key, value := split[0], split[1] - if strings.HasPrefix(key, config.E2ETestEnvVarPrefix) { - buffer.WriteString(fmt.Sprintf("%s=%s\n", key, value)) - } - } - - return buffer.String() -} - -func jobEnvVars(props *Props) *[]*k8s.EnvVar { - // Use a map to set values so we can easily overwrite duplicate values - env := make(map[string]string) - - // Propagate common environment variables to the runner - lookups := []string{ - config.EnvVarCLImage, - config.EnvVarCLTag, - config.EnvVarCLCommitSha, - config.EnvVarLogLevel, - config.EnvVarTestTrigger, - config.EnvVarToleration, - config.EnvVarSlackChannel, - config.EnvVarSlackKey, - config.EnvVarSlackUser, - config.EnvVarUser, - config.EnvVarTeam, - config.EnvVarNodeSelector, - config.EnvVarDBURL, - config.EnvVarInternalDockerRepo, - config.EnvVarLocalCharts, - config.EnvBase64ConfigOverride, - config.EnvSethLogLevel, - } - for _, k := range lookups { - v, success := os.LookupEnv(k) - if success && len(v) > 0 { - log.Debug().Str(k, v).Msg("Forwarding Env Var") - env[k] = v - } - } - - // Propagate prefixed variables to the runner - // These should overwrite anything that was unprefixed if they match up - for _, e := range os.Environ() { - if i := strings.Index(e, "="); i >= 0 { - if strings.HasPrefix(e[:i], config.EnvVarPrefix) { - withoutPrefix := strings.Replace(e[:i], config.EnvVarPrefix, "", 1) - log.Debug().Str(e[:i], e[i+1:]).Msg("Forwarding generic Env Var") - env[withoutPrefix] = e[i+1:] - } - } - } - - // Add variables that should need specific values for the remote runner - env[config.EnvVarNamespace] = props.TargetNamespace - env["TEST_NAME"] = props.TestName - env[config.EnvVarInsideK8s] = "true" - env[config.EnvVarSkipManifestUpdate] = strconv.FormatBool(props.SkipManifestUpdate) - - // convert from map to the expected array - cdk8sVars := make([]*k8s.EnvVar, 0) - for k, v := range env { - cdk8sVars = append(cdk8sVars, a.EnvVarStr(k, v)) - } - return &cdk8sVars -} diff --git a/lib/k8s/examples/clones/clones.go b/lib/k8s/examples/clones/clones.go deleted file mode 100644 index 7744d9cbe..000000000 --- a/lib/k8s/examples/clones/clones.go +++ /dev/null @@ -1,53 +0,0 @@ -package main - -import ( - "fmt" - - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/environment" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/chainlink" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/ethereum" -) - -func main() { - // Multiple environments of the same type/chart - err := environment.New(&environment.Config{ - Labels: []string{fmt.Sprintf("envType=%s", pkg.EnvTypeEVM5)}, - KeepConnection: true, - RemoveOnInterrupt: true, - }). - AddHelm(ethereum.New(nil)). - AddHelm(chainlink.New(0, map[string]interface{}{ - "chainlink": map[string]interface{}{ - "resources": map[string]interface{}{ - "requests": map[string]interface{}{ - "cpu": "344m", - }, - "limits": map[string]interface{}{ - "cpu": "344m", - }, - }, - }, - "db": map[string]interface{}{ - "stateful": "true", - "capacity": "1Gi", - }, - })). - AddHelm(chainlink.New(1, - map[string]interface{}{ - "chainlink": map[string]interface{}{ - "resources": map[string]interface{}{ - "requests": map[string]interface{}{ - "cpu": "577m", - }, - "limits": map[string]interface{}{ - "cpu": "577m", - }, - }, - }, - })). - Run() - if err != nil { - panic(err) - } -} diff --git a/lib/k8s/examples/concurrent/env_test.go b/lib/k8s/examples/concurrent/env_test.go deleted file mode 100644 index e81b23dba..000000000 --- a/lib/k8s/examples/concurrent/env_test.go +++ /dev/null @@ -1,36 +0,0 @@ -package concurrent_test - -import ( - "testing" - - "github.com/stretchr/testify/require" - - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/environment" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/chainlink" -) - -func TestConcurrentEnvs(t *testing.T) { - t.Run("test 1", func(t *testing.T) { - t.Parallel() - e := environment.New(nil). - AddHelm(chainlink.New(0, nil)) - defer e.Shutdown() - err := e.Run() - require.NoError(t, err) - }) - t.Run("test 2", func(t *testing.T) { - t.Parallel() - e := environment.New(nil). - AddHelm(chainlink.New(0, nil)) - defer e.Shutdown() - err := e.Run() - require.NoError(t, err) - e, err = e. - ReplaceHelm("chainlink-0", chainlink.New(0, map[string]any{ - "replicas": 2, - })) - require.NoError(t, err) - err = e.Run() - require.NoError(t, err) - }) -} diff --git a/lib/k8s/examples/coverage/Dockerfile b/lib/k8s/examples/coverage/Dockerfile deleted file mode 100644 index 503560213..000000000 --- a/lib/k8s/examples/coverage/Dockerfile +++ /dev/null @@ -1,5 +0,0 @@ -FROM golang:1.21-buster - -RUN curl -s https://api.github.com/repos/qiniu/goc/releases/latest | grep "browser_download_url.*-linux-amd64.tar.gz" | cut -d : -f 2,3 | tr -d \" | xargs -n 1 curl -L | tar -zx && chmod +x goc && mv goc /usr/local/bin - -CMD ["goc", "server"] diff --git a/lib/k8s/examples/coverage/Dockerfile.target b/lib/k8s/examples/coverage/Dockerfile.target deleted file mode 100644 index a8a75d4fc..000000000 --- a/lib/k8s/examples/coverage/Dockerfile.target +++ /dev/null @@ -1,8 +0,0 @@ -FROM public.ecr.aws/chainlink/goc:latest - -COPY . app/ -WORKDIR app/cmd -RUN goc build -o service1 . --center http://goc:7777 -RUN chmod +x ../entrypoint.sh - -CMD ["../entrypoint.sh"] diff --git a/lib/k8s/examples/coverage/entrypoint.sh b/lib/k8s/examples/coverage/entrypoint.sh deleted file mode 100755 index 49b87b603..000000000 --- a/lib/k8s/examples/coverage/entrypoint.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env bash -sleep 30 && ./service1 diff --git a/lib/k8s/examples/coverage/env.go b/lib/k8s/examples/coverage/env.go deleted file mode 100644 index 4bc6e612c..000000000 --- a/lib/k8s/examples/coverage/env.go +++ /dev/null @@ -1,27 +0,0 @@ -package main - -import ( - "time" - - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/environment" - goc "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/cdk8s/goc" - dummy "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/cdk8s/http_dummy" -) - -func main() { - e := environment.New(nil). - AddChart(goc.New()). - AddChart(dummy.New()) - if err := e.Run(); err != nil { - panic(err) - } - // run your test logic here - time.Sleep(1 * time.Minute) - if err := e.SaveCoverage(); err != nil { - panic(err) - } - // clear the coverage, rerun the tests again if needed - if err := e.ClearCoverage(); err != nil { - panic(err) - } -} diff --git a/lib/k8s/examples/deployment_part/cmd/env.go b/lib/k8s/examples/deployment_part/cmd/env.go deleted file mode 100644 index 6f6e055eb..000000000 --- a/lib/k8s/examples/deployment_part/cmd/env.go +++ /dev/null @@ -1,38 +0,0 @@ -package main - -import ( - "time" - - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/environment" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/examples/deployment_part" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/chainlink" -) - -func main() { - e := environment.New(&environment.Config{ - NamespacePrefix: "adding-new-deployment-part", - TTL: 3 * time.Hour, - KeepConnection: true, - RemoveOnInterrupt: true, - }). - AddHelm(deployment_part.New(nil)). - AddHelm(chainlink.New(0, map[string]interface{}{ - "replicas": 5, - "env": map[string]interface{}{ - "SOLANA_ENABLED": "true", - "EVM_ENABLED": "false", - "EVM_RPC_ENABLED": "false", - "CHAINLINK_DEV": "false", - "FEATURE_OFFCHAIN_REPORTING2": "true", - "feature_offchain_reporting": "false", - "P2P_NETWORKING_STACK": "V2", - "P2PV2_LISTEN_ADDRESSES": "0.0.0.0:6690", - "P2PV2_DELTA_DIAL": "5s", - "P2PV2_DELTA_RECONCILE": "5s", - "p2p_listen_port": "0", - }, - })) - if err := e.Run(); err != nil { - panic(err) - } -} diff --git a/lib/k8s/examples/deployment_part/sol.go b/lib/k8s/examples/deployment_part/sol.go deleted file mode 100644 index 40832d4ad..000000000 --- a/lib/k8s/examples/deployment_part/sol.go +++ /dev/null @@ -1,117 +0,0 @@ -package deployment_part - -import ( - "github.com/rs/zerolog/log" - - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/client" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/environment" -) - -type Props struct { - NetworkName string `envconfig:"network_name"` - HttpURLs []string `envconfig:"http_url"` - WsURLs []string `envconfig:"ws_url"` - Values map[string]interface{} -} - -type HelmProps struct { - Name string - Path string - Version string - Values *map[string]interface{} -} - -type Chart struct { - HelmProps *HelmProps - Props *Props -} - -func (m Chart) IsDeploymentNeeded() bool { - return true -} - -func (m Chart) GetProps() interface{} { - return m.Props -} - -func (m Chart) GetName() string { - return m.HelmProps.Name -} - -func (m Chart) GetPath() string { - return m.HelmProps.Path -} - -func (m Chart) GetVersion() string { - return m.HelmProps.Version -} - -func (m Chart) GetValues() *map[string]interface{} { - return m.HelmProps.Values -} - -func (m Chart) GetLabels() map[string]string { - return map[string]string{ - "chain.link/component": "solana-validator", - } -} - -func (m Chart) ExportData(e *environment.Environment) error { - netLocal, err := e.Fwd.FindPort("sol:0", "sol-val", "http-rpc").As(client.LocalConnection, client.HTTP) - if err != nil { - return err - } - netLocalWS, err := e.Fwd.FindPort("sol:0", "sol-val", "ws-rpc").As(client.LocalConnection, client.WS) - if err != nil { - return err - } - netInternal, err := e.Fwd.FindPort("sol:0", "sol-val", "http-rpc").As(client.RemoteConnection, client.HTTP) - if err != nil { - return err - } - e.URLs[m.Props.NetworkName] = []string{netLocal, netLocalWS} - if e.Cfg.InsideK8s { - e.URLs[m.Props.NetworkName] = []string{netInternal} - } - log.Info().Str("Name", m.Props.NetworkName).Str("URLs", netLocal).Msg("Solana network") - return nil -} - -func defaultProps() *Props { - return &Props{ - NetworkName: "sol", - Values: map[string]interface{}{ - "replicas": "1", - "sol": map[string]interface{}{ - "image": map[string]interface{}{ - "image": "solanalabs/solana", - "version": "v1.9.14", - }, - "resources": map[string]interface{}{ - "requests": map[string]interface{}{ - "cpu": "2000m", - "memory": "4000Mi", - }, - "limits": map[string]interface{}{ - "cpu": "2000m", - "memory": "4000Mi", - }, - }, - }, - }, - } -} - -func New(props *Props) environment.ConnectedChart { - if props == nil { - props = defaultProps() - } - return Chart{ - HelmProps: &HelmProps{ - Name: "sol", - Path: "chainlink-qa/solana-validator", - Values: &props.Values, - }, - Props: props, - } -} diff --git a/lib/k8s/examples/deployment_part_cdk8s/blockscout.go b/lib/k8s/examples/deployment_part_cdk8s/blockscout.go deleted file mode 100644 index a50c1df37..000000000 --- a/lib/k8s/examples/deployment_part_cdk8s/blockscout.go +++ /dev/null @@ -1,220 +0,0 @@ -package deployment_part_cdk8s - -import ( - "fmt" - - cdk8s "github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2" - "github.com/rs/zerolog/log" - - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/client" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/config" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/environment" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/imports/k8s" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg" - a "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/alias" - "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/ptr" -) - -const ( - URLsKey = "blockscout" -) - -type Chart struct { - Props *Props -} - -func (m Chart) IsDeploymentNeeded() bool { - return true -} - -func (m Chart) GetName() string { - return "blockscout" -} - -func (m Chart) GetProps() interface{} { - return m.Props -} - -func (m Chart) GetPath() string { - return "" -} - -func (m Chart) GetVersion() string { - return "" -} - -func (m Chart) GetValues() *map[string]interface{} { - return nil -} - -func (m Chart) GetLabels() map[string]string { - return map[string]string{ - "chain.link/component": "blockscout", - } -} - -func (m Chart) ExportData(e *environment.Environment) error { - bsURL, err := e.Fwd.FindPort("blockscout:0", "blockscout-node", "explorer").As(client.LocalConnection, client.HTTP) - if err != nil { - return err - } - log.Info().Str("URL", bsURL).Msg("Blockscout explorer") - e.URLs[URLsKey] = []string{bsURL} - return nil -} - -func New(props *Props) func(root cdk8s.Chart) environment.ConnectedChart { - return func(root cdk8s.Chart) environment.ConnectedChart { - dp := defaultProps() - config.MustMerge(dp, props) - c := &Chart{ - Props: dp, - } - vars := vars{ - Labels: &map[string]*string{ - "app": ptr.Ptr(c.GetName()), - }, - ConfigMapName: fmt.Sprintf("%s-cm", c.GetName()), - BaseName: c.GetName(), - Port: 4000, - Props: dp, - } - service(root, vars) - deployment(root, vars) - return c - } -} - -type Props struct { - HttpURL string `envconfig:"http_url"` - WsURL string `envconfig:"ws_url"` -} - -func defaultProps() *Props { - return &Props{ - HttpURL: "http://geth:8544", - WsURL: "ws://geth:8546", - } -} - -// vars some shared labels/selectors and names that must match in resources -type vars struct { - Labels *map[string]*string - BaseName string - ConfigMapName string - Port float64 - Props *Props -} - -func service(chart cdk8s.Chart, vars vars) { - k8s.NewKubeService(chart, ptr.Ptr(fmt.Sprintf("%s-service", vars.BaseName)), &k8s.KubeServiceProps{ - Metadata: &k8s.ObjectMeta{ - Name: ptr.Ptr(vars.BaseName), - }, - Spec: &k8s.ServiceSpec{ - Ports: &[]*k8s.ServicePort{ - { - Name: ptr.Ptr("explorer"), - Port: ptr.Ptr(vars.Port), - TargetPort: k8s.IntOrString_FromNumber(ptr.Ptr[float64](4000)), - }, - }, - Selector: vars.Labels, - }, - }) -} - -func postgresContainer(p vars) *k8s.Container { - return &k8s.Container{ - Name: ptr.Ptr(fmt.Sprintf("%s-db", p.BaseName)), - Image: ptr.Ptr("postgres:13.6"), - Ports: &[]*k8s.ContainerPort{ - { - Name: ptr.Ptr("postgres"), - ContainerPort: ptr.Ptr[float64](5432), - }, - }, - Env: &[]*k8s.EnvVar{ - a.EnvVarStr("POSTGRES_PASSWORD", "postgres"), - a.EnvVarStr("POSTGRES_DB", "blockscout"), - }, - LivenessProbe: &k8s.Probe{ - Exec: &k8s.ExecAction{ - Command: pkg.PGIsReadyCheck()}, - InitialDelaySeconds: ptr.Ptr[float64](60), - PeriodSeconds: ptr.Ptr[float64](60), - }, - ReadinessProbe: &k8s.Probe{ - Exec: &k8s.ExecAction{ - Command: pkg.PGIsReadyCheck()}, - InitialDelaySeconds: ptr.Ptr[float64](2), - PeriodSeconds: ptr.Ptr[float64](2), - }, - Resources: a.ContainerResources("1000m", "2048Mi", "1000m", "2048Mi"), - } -} - -func deployment(chart cdk8s.Chart, vars vars) { - k8s.NewKubeDeployment( - chart, - ptr.Ptr(fmt.Sprintf("%s-deployment", vars.BaseName)), - &k8s.KubeDeploymentProps{ - Metadata: &k8s.ObjectMeta{ - Name: ptr.Ptr(vars.BaseName), - }, - Spec: &k8s.DeploymentSpec{ - Selector: &k8s.LabelSelector{ - MatchLabels: vars.Labels, - }, - Template: &k8s.PodTemplateSpec{ - Metadata: &k8s.ObjectMeta{ - Labels: vars.Labels, - }, - Spec: &k8s.PodSpec{ - ServiceAccountName: ptr.Ptr("default"), - Containers: &[]*k8s.Container{ - container(vars), - postgresContainer(vars), - }, - }, - }, - }, - }) -} - -func container(vars vars) *k8s.Container { - return &k8s.Container{ - Name: ptr.Ptr(fmt.Sprintf("%s-node", vars.BaseName)), - Image: ptr.Ptr("f4hrenh9it/blockscout:v1"), - ImagePullPolicy: ptr.Ptr("Always"), - Command: &[]*string{ptr.Ptr(`/bin/bash`)}, - Args: &[]*string{ - ptr.Ptr("-c"), - ptr.Ptr("mix ecto.create && mix ecto.migrate && mix phx.server"), - }, - Ports: &[]*k8s.ContainerPort{ - { - Name: ptr.Ptr("explorer"), - ContainerPort: ptr.Ptr(vars.Port), - }, - }, - ReadinessProbe: &k8s.Probe{ - HttpGet: &k8s.HttpGetAction{ - Port: k8s.IntOrString_FromNumber(ptr.Ptr(vars.Port)), - Path: ptr.Ptr("/"), - }, - InitialDelaySeconds: ptr.Ptr[float64](20), - PeriodSeconds: ptr.Ptr[float64](5), - }, - Env: &[]*k8s.EnvVar{ - a.EnvVarStr("MIX_ENV", "prod"), - a.EnvVarStr("ECTO_USE_SSL", "'false'"), - a.EnvVarStr("COIN", "DAI"), - a.EnvVarStr("ETHEREUM_JSONRPC_VARIANT", "geth"), - a.EnvVarStr("ETHEREUM_JSONRPC_HTTP_URL", vars.Props.HttpURL), - a.EnvVarStr("ETHEREUM_JSONRPC_WS_URL", vars.Props.WsURL), - a.EnvVarStr("DATABASE_URL", "postgresql://postgres:@localhost:5432/blockscout?ssl=false"), - }, - Resources: a.ContainerResources("300m", "2048Mi", "300m", "2048Mi"), - } -} diff --git a/lib/k8s/examples/deployment_part_cdk8s/cmd/env.go b/lib/k8s/examples/deployment_part_cdk8s/cmd/env.go deleted file mode 100644 index 6f6d7b74b..000000000 --- a/lib/k8s/examples/deployment_part_cdk8s/cmd/env.go +++ /dev/null @@ -1,21 +0,0 @@ -package main - -import ( - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/environment" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/examples/deployment_part_cdk8s" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/chainlink" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/ethereum" -) - -func main() { - e := environment.New(nil). - AddChart(deployment_part_cdk8s.New(&deployment_part_cdk8s.Props{})). - AddHelm(ethereum.New(nil)). - AddHelm(chainlink.New(0, map[string]interface{}{ - "replicas": 2, - })) - if err := e.Run(); err != nil { - panic(err) - } - e.Shutdown() -} diff --git a/lib/k8s/examples/dump/env.go b/lib/k8s/examples/dump/env.go deleted file mode 100644 index dfb7b0be4..000000000 --- a/lib/k8s/examples/dump/env.go +++ /dev/null @@ -1,19 +0,0 @@ -package main - -import ( - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/environment" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/chainlink" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/ethereum" -) - -func main() { - e := environment.New(nil). - AddHelm(ethereum.New(nil)). - AddHelm(chainlink.New(0, nil)) - if err := e.Run(); err != nil { - panic(err) - } - if err := e.DumpLogs("logs/mytest"); err != nil { - panic(err) - } -} diff --git a/lib/k8s/examples/link/Dockerfile b/lib/k8s/examples/link/Dockerfile deleted file mode 100644 index a0e521d13..000000000 --- a/lib/k8s/examples/link/Dockerfile +++ /dev/null @@ -1,62 +0,0 @@ -# base test for all k8s test runs -FROM golang:1.23-bullseye - -ARG BASE_URL -ARG HELM_VERSION -ARG HOME -ARG KUBE_VERSION -ARG NODE_VERSION - -ENV GOOS="linux" -ENV BASE_URL="https://get.helm.sh" -ENV HELM_VERSION="3.10.3" -ENV KUBE_VERSION="v1.25.5" -ENV NODE_VERSION=18 - -RUN apt-get update && apt-get install -y ca-certificates wget curl git gnupg zip && \ - mkdir -p /etc/apt/keyrings && \ - curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg && \ - echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_VERSION.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list && \ - apt-get update && apt-get install -y nodejs && \ - curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl && \ - chmod +x ./kubectl && \ - mv ./kubectl /usr/local/bin && \ - case `uname -m` in \ - x86_64) ARCH=amd64; ;; \ - armv7l) ARCH=arm; ;; \ - aarch64) ARCH=arm64; ;; \ - ppc64le) ARCH=ppc64le; ;; \ - s390x) ARCH=s390x; ;; \ - *) echo "un-supported arch, exit ..."; exit 1; ;; \ - esac && \ - wget ${BASE_URL}/helm-v${HELM_VERSION}-linux-${ARCH}.tar.gz -O - | tar -xz && \ - mv linux-${ARCH}/helm /usr/bin/helm && \ - chmod +x /usr/bin/helm && \ - rm -rf linux-${ARCH} && \ - npm install -g yarn && \ - apt-get clean all && \ - helm repo add chainlink-qa https://raw.githubusercontent.com/smartcontractkit/qa-charts/gh-pages/ && \ - helm repo add bitnami https://charts.bitnami.com/bitnami && \ - helm repo update - -# This is needed, because kubectl config used is configured to use AWSCLI v2 -RUN case `uname -m` in \ - x86_64) AWS_ARCH=x86_64; ;; \ - armv7l) AWS_ARCH=armv7l; ;; \ - aarch64) AWS_ARCH=aarch64; ;; \ - *) echo "un-supported arch, exit ..."; exit 1; ;; \ - esac && \ - curl https://awscli.amazonaws.com/awscli-exe-linux-${AWS_ARCH}.zip -o "awscliv2.zip" && \ - unzip awscliv2.zip && \ - ./aws/install && \ - rm -rf awscliv2.zip - -COPY lib/ testdir/ -WORKDIR /go/testdir/k8s/examples/link - -ENV GOARCH=amd64 -ENV GOOS=linux - -RUN go test -c . -o link - -ENTRYPOINT ["./link"] \ No newline at end of file diff --git a/lib/k8s/examples/link/link_test.go b/lib/k8s/examples/link/link_test.go deleted file mode 100644 index 7b4784927..000000000 --- a/lib/k8s/examples/link/link_test.go +++ /dev/null @@ -1,193 +0,0 @@ -package link - -import ( - "math/big" - "testing" - "time" - - "github.com/ethereum/go-ethereum/common" - "github.com/rs/zerolog/log" - - "github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain" - ctf_config "github.com/smartcontractkit/chainlink-testing-framework/lib/config" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/environment" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/chainlink" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/ethereum" - "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/ptr" - "github.com/smartcontractkit/chainlink-testing-framework/seth" - "github.com/smartcontractkit/chainlink-testing-framework/seth/contracts/bind/link_token_interface" -) - -func TestSimpleDONWithLinkContract(t *testing.T) { - tomlConfig := `[Feature] -FeedsManager = true -LogPoller = true -UICSAKeys = true - -[Database] -MaxIdleConns = 20 -MaxOpenConns = 40 -MigrateOnStartup = true - -[Log] -Level = "debug" -JSONConsole = true - -[Log.File] -MaxSize = "0b" - -[WebServer] -AllowOrigins = "*" -HTTPWriteTimeout = "3m0s" -HTTPPort = 6688 -SecureCookies = false -SessionTimeout = "999h0m0s" - -[WebServer.RateLimit] -Authenticated = 2000 -Unauthenticated = 1000 - -[WebServer.TLS] -HTTPSPort = 0 - -[OCR] -Enabled = true - -[P2P] - -[P2P.V2] -ListenAddresses = ["0.0.0.0:6690"] - -[[EVM]] -ChainID = "1337" -AutoCreateKey = true -FinalityDepth = 1 -MinContractPayment = "0" - -[EVM.GasEstimator] -PriceMax = "200 gwei" -LimitDefault = 6000000 -FeeCapDefault = "200 gwei" - -[[EVM.Nodes]] -Name = "Simulated Geth-0" -WSURL = "ws://geth:8546" -HTTPURL = "http://geth:8544"` - - chainlinkImageCfg := &ctf_config.ChainlinkImageConfig{ - Image: ptr.Ptr("public.ecr.aws/chainlink/chainlink"), - Version: ptr.Ptr("2.19.0"), - } - - var overrideFn = func(_ interface{}, target interface{}) { - ctf_config.MustConfigOverrideChainlinkVersion(chainlinkImageCfg, target) - } - - cd := chainlink.NewWithOverride(0, map[string]any{ - "replicas": 6, - "toml": tomlConfig, - "db": map[string]any{ - "stateful": true, // stateful DB by default for soak tests - }, - "prometheus": true, - }, chainlinkImageCfg, overrideFn) - - productName := "data-feedsv1.0" - nsLabels, err := environment.GetRequiredChainLinkNamespaceLabels(productName, "soak") - if err != nil { - t.Fatal("Error creating required chain.link labels for namespace", err) - } - - workloadPodLabels, err := environment.GetRequiredChainLinkWorkloadAndPodLabels(productName, "soak") - if err != nil { - t.Fatal("Error creating required chain.link labels for workload and pod", err) - } - - baseEnvironmentConfig := &environment.Config{ - TTL: time.Hour * 720, // 30 days, - NamespacePrefix: "bartek-ocr", - Test: t, - PreventPodEviction: true, - Labels: nsLabels, - WorkloadLabels: workloadPodLabels, - PodLabels: workloadPodLabels, - } - - nodeNetwork := blockchain.SimulatedEVMNetwork - - ethProps := ðereum.Props{ - NetworkName: nodeNetwork.Name, - Simulated: nodeNetwork.Simulated, - WsURLs: nodeNetwork.URLs, - HttpURLs: nodeNetwork.HTTPURLs, - } - - testEnv := environment.New(baseEnvironmentConfig). - AddHelm(ethereum.New(ethProps)). - AddHelm(cd) - - err = testEnv.Run() - if err != nil { - t.Fatal("Error running environment: ", err) - } - - log.Info().Bool("Remote runner?", testEnv.WillUseRemoteRunner()).Msg("Started environment") - - if testEnv.WillUseRemoteRunner() { - log.Info().Msg("Exiting as test will use remote runner") - return - } - - // if test is running inside K8s, nothing to do, default network urls are correct - if !testEnv.Cfg.InsideK8s { - // Test is running locally, set forwarded URL of Geth blockchain node - wsURLs := testEnv.URLs[blockchain.SimulatedEVMNetwork.Name] - httpURLs := testEnv.URLs[blockchain.SimulatedEVMNetwork.Name+"_http"] - if len(wsURLs) == 0 || len(httpURLs) == 0 { - t.Fatal("Forwarded Geth URLs should not be empty") - } - nodeNetwork.URLs = wsURLs - nodeNetwork.HTTPURLs = httpURLs - } - - sethClient, err := seth.NewClientBuilder(). - WithRpcUrl(nodeNetwork.URLs[0]). - WithPrivateKeys([]string{nodeNetwork.PrivateKeys[0]}). - Build() - if err != nil { - t.Fatal("Error creating Seth client", err) - } - - for i := 0; i < 5; i++ { - log.Info(). - Msgf("Deploying LinkToken contract, instance %d/%d", i+1, 5) - - linkTokenAbi, err := link_token_interface.LinkTokenMetaData.GetAbi() - if err != nil { - t.Fatal("Error getting LinkToken ABI", err) - } - linkDeploymentData, err := sethClient.DeployContract(sethClient.NewTXOpts(), "LinkToken", *linkTokenAbi, common.FromHex(link_token_interface.LinkTokenMetaData.Bin)) - if err != nil { - t.Fatal("Error deploying LinkToken contract", err) - } - linkToken, err := link_token_interface.NewLinkToken(linkDeploymentData.Address, sethClient.Client) - if err != nil { - t.Fatal("Error creating LinkToken contract instance", err) - } - - totalSupply, err := linkToken.TotalSupply(sethClient.NewCallOpts()) - if err != nil { - t.Fatal("Error getting total supply of LinkToken", err) - } - - if totalSupply.Cmp(big.NewInt(0)) <= 0 { - t.Fatal("Total supply of LinkToken should be greater than 0") - } - - time.Sleep(15 * time.Second) - } - - // here you could proceed with your test logic - // for example, by deploying other contracts, funding accounts, etc. - // and maybe generating some load on the system using WASP? -} diff --git a/lib/k8s/examples/modify_cdk8s/env.go b/lib/k8s/examples/modify_cdk8s/env.go deleted file mode 100644 index 1eef6906e..000000000 --- a/lib/k8s/examples/modify_cdk8s/env.go +++ /dev/null @@ -1,42 +0,0 @@ -package main - -import ( - "fmt" - - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/environment" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/cdk8s/blockscout" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/chainlink" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/ethereum" -) - -func main() { - e := environment.New(&environment.Config{ - NamespacePrefix: "modified-env", - Labels: []string{fmt.Sprintf("envType=Modified")}, - }). - AddChart(blockscout.New(&blockscout.Props{ - WsURL: "ws://geth:8546", - HttpURL: "http://geth:8544", - })). - AddHelm(ethereum.New(nil)). - AddHelm(chainlink.New(0, map[string]interface{}{ - "replicas": 1, - })) - err := e.Run() - if err != nil { - panic(err) - } - e.ClearCharts() - err = e. - AddChart(blockscout.New(&blockscout.Props{ - HttpURL: "http://geth:9000", - })). - AddHelm(ethereum.New(nil)). - AddHelm(chainlink.New(0, map[string]interface{}{ - "replicas": 1, - })). - Run() - if err != nil { - panic(err) - } -} diff --git a/lib/k8s/examples/modify_helm/env.go b/lib/k8s/examples/modify_helm/env.go deleted file mode 100644 index 8a27effc8..000000000 --- a/lib/k8s/examples/modify_helm/env.go +++ /dev/null @@ -1,41 +0,0 @@ -package main - -import ( - "fmt" - - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/environment" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/chainlink" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/ethereum" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/mockserver" - mockservercfg "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/mockserver-cfg" -) - -func main() { - e := environment.New(&environment.Config{ - NamespacePrefix: "modified-env", - Labels: []string{fmt.Sprintf("envType=Modified")}, - }). - AddHelm(mockservercfg.New(nil)). - AddHelm(mockserver.New(nil)). - AddHelm(ethereum.New(nil)). - AddHelm(chainlink.New(0, map[string]any{ - "replicas": 1, - })) - err := e.Run() - if err != nil { - panic(err) - } - e.Cfg.KeepConnection = true - e.Cfg.RemoveOnInterrupt = true - e, err = e. - ReplaceHelm("chainlink-0", chainlink.New(0, map[string]any{ - "replicas": 2, - })) - if err != nil { - panic(err) - } - err = e.Run() - if err != nil { - panic(err) - } -} diff --git a/lib/k8s/examples/multistage/env.go b/lib/k8s/examples/multistage/env.go deleted file mode 100644 index 9029dc130..000000000 --- a/lib/k8s/examples/multistage/env.go +++ /dev/null @@ -1,36 +0,0 @@ -package main - -import ( - "time" - - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/environment" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/chainlink" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/ethereum" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/mockserver" - mockservercfg "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/mockserver-cfg" -) - -func main() { - e := environment.New(&environment.Config{TTL: 20 * time.Minute}) - err := e. - AddHelm(ethereum.New(nil)). - AddHelm(chainlink.New(0, nil)). - Run() - if err != nil { - panic(err) - } - // deploy another part - e.Cfg.KeepConnection = true - err = e. - AddHelm(chainlink.New(1, nil)). - AddHelm(mockservercfg.New(nil)). - AddHelm(mockserver.New(nil)). - Run() - defer func() { - errr := e.Shutdown() - panic(errr) - }() - if err != nil { - panic(err) - } -} diff --git a/lib/k8s/examples/multistage/someData.txt b/lib/k8s/examples/multistage/someData.txt deleted file mode 100644 index 44555c3a7..000000000 --- a/lib/k8s/examples/multistage/someData.txt +++ /dev/null @@ -1 +0,0 @@ -data to copy diff --git a/lib/k8s/examples/quick-debug/env.go b/lib/k8s/examples/quick-debug/env.go deleted file mode 100644 index 40bcf753e..000000000 --- a/lib/k8s/examples/quick-debug/env.go +++ /dev/null @@ -1,22 +0,0 @@ -package main - -import ( - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/environment" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/chainlink" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/ethereum" -) - -func main() { - err := environment.New(&environment.Config{ - Labels: []string{"type=construction-in-progress"}, - NamespacePrefix: "new-environment", - KeepConnection: true, - RemoveOnInterrupt: true, - }). - AddHelm(ethereum.New(nil)). - AddHelm(chainlink.New(0, nil)). - Run() - if err != nil { - panic(err) - } -} diff --git a/lib/k8s/examples/remote-test-runner/env.go b/lib/k8s/examples/remote-test-runner/env.go deleted file mode 100644 index 9a5ca7692..000000000 --- a/lib/k8s/examples/remote-test-runner/env.go +++ /dev/null @@ -1,34 +0,0 @@ -package main - -import ( - "os" - - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/config" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/environment" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/chainlink" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/ethereum" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/mockserver" - mockservercfg "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/mockserver-cfg" -) - -func main() { - // see REMOTE_RUN.md for tutorial - e := environment.New(&environment.Config{ - NamespacePrefix: "zmytest", - }). - AddHelm(mockservercfg.New(nil)). - AddHelm(mockserver.New(nil)). - AddHelm(ethereum.New(nil)). - AddHelm(chainlink.New(0, map[string]interface{}{ - "replicas": 1, - "chainlink": map[string]interface{}{ - "image": map[string]interface{}{ - "image": os.Getenv(config.EnvVarCLImage), - "version": os.Getenv(config.EnvVarCLTag), - }, - }, - })) - if err := e.Run(); err != nil { - panic(err) - } -} diff --git a/lib/k8s/examples/resources/env.go b/lib/k8s/examples/resources/env.go deleted file mode 100644 index 10a3f8f3a..000000000 --- a/lib/k8s/examples/resources/env.go +++ /dev/null @@ -1,31 +0,0 @@ -package main - -import ( - "fmt" - - "github.com/rs/zerolog/log" - - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/environment" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/chainlink" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/ethereum" -) - -func main() { - e := environment.New(&environment.Config{ - Labels: []string{fmt.Sprintf("envType=%s", pkg.EnvTypeEVM5)}, - }). - AddHelm(ethereum.New(nil)). - AddHelm(chainlink.New(0, nil)) - err := e.Run() - if err != nil { - panic(err) - } - // default k8s selector - summ, err := e.ResourcesSummary("app in (chainlink-0, geth)") - if err != nil { - panic(err) - } - log.Warn().Interface("Resources", summ).Send() - e.Shutdown() -} diff --git a/lib/k8s/examples/simple/env.go b/lib/k8s/examples/simple/env.go deleted file mode 100644 index bc3faec39..000000000 --- a/lib/k8s/examples/simple/env.go +++ /dev/null @@ -1,27 +0,0 @@ -package main - -import ( - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/environment" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/chainlink" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/ethereum" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/mockserver" - mockservercfg "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/mockserver-cfg" -) - -func main() { - err := environment.New(&environment.Config{ - NamespacePrefix: "ztest", - KeepConnection: true, - RemoveOnInterrupt: true, - }). - AddHelm(mockservercfg.New(nil)). - AddHelm(mockserver.New(nil)). - AddHelm(ethereum.New(nil)). - AddHelm(chainlink.New(0, map[string]interface{}{ - "replicas": 1, - })). - Run() - if err != nil { - panic(err) - } -} diff --git a/lib/k8s/examples/simple_toml/env_toml_config.go b/lib/k8s/examples/simple_toml/env_toml_config.go deleted file mode 100644 index 4e0ba6bda..000000000 --- a/lib/k8s/examples/simple_toml/env_toml_config.go +++ /dev/null @@ -1,53 +0,0 @@ -package main - -import ( - ctf_config "github.com/smartcontractkit/chainlink-testing-framework/lib/config" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/environment" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/chainlink" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/ethereum" - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/mockserver" - mockservercfg "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/pkg/helm/mockserver-cfg" - "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/ptr" -) - -func main() { - // in actual implementation here you should read the config from TOML file instead of creating structs manually - chainlinkConfig := ctf_config.ChainlinkImageConfig{ - Image: ptr.Ptr("public.ecr.aws/chainlink/chainlink"), - Version: ptr.Ptr("2.18.0"), - PostgresVersion: ptr.Ptr("12.0"), - } - - pyroscope := ctf_config.PyroscopeConfig{ - Enabled: ptr.Ptr(false), - } - - config := struct { - Chainlink ctf_config.ChainlinkImageConfig - Pyroscope ctf_config.PyroscopeConfig - }{ - Chainlink: chainlinkConfig, - Pyroscope: pyroscope, - } - - var overrideFn = func(_ interface{}, target interface{}) { - ctf_config.MustConfigOverrideChainlinkVersion(&chainlinkConfig, target) - ctf_config.MightConfigOverridePyroscopeKey(&pyroscope, target) - } - - err := environment.New(&environment.Config{ - NamespacePrefix: "ztest", - KeepConnection: true, - RemoveOnInterrupt: true, - }). - AddHelm(mockservercfg.New(nil)). - AddHelm(mockserver.New(nil)). - AddHelm(ethereum.New(nil)). - AddHelm(chainlink.NewWithOverride(0, map[string]interface{}{ - "replicas": 1, - }, &config, overrideFn)). - Run() - if err != nil { - panic(err) - } -} diff --git a/lib/k8s/grafana/cl_insights.json b/lib/k8s/grafana/cl_insights.json deleted file mode 100644 index b42e5d452..000000000 --- a/lib/k8s/grafana/cl_insights.json +++ /dev/null @@ -1,3011 +0,0 @@ -{ - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": { - "type": "datasource", - "uid": "grafana" - }, - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "target": { - "limit": 100, - "matchAny": false, - "tags": [], - "type": "dashboard" - }, - "type": "dashboard" - } - ] - }, - "description": "A look at the components of Chainlink Integration tests", - "editable": true, - "fiscalYearStartMonth": 0, - "graphTooltip": 0, - "iteration": 1662412920215, - "links": [], - "liveNow": false, - "panels": [ - { - "collapsed": true, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 0 - }, - "id": 161, - "panels": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "Components health", - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 20, - "w": 24, - "x": 0, - "y": 1 - }, - "id": 163, - "options": { - "colorMode": "value", - "graphMode": "area", - "justifyMode": "auto", - "orientation": "auto", - "reduceOptions": { - "calcs": ["last"], - "fields": "", - "values": false - }, - "text": { - "titleSize": 14, - "valueSize": 14 - }, - "textMode": "name" - }, - "pluginVersion": "8.3.5", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "health{namespace=\"$namespace\", pod=\"$cl_node\"}", - "interval": "", - "legendFormat": "service: {{service_id}}", - "refId": "A" - } - ], - "title": "Components health", - "transparent": true, - "type": "stat" - } - ], - "title": "Components health", - "type": "row" - }, - { - "collapsed": true, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 1 - }, - "id": 181, - "panels": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "Overall log count by type", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 2 - }, - "id": 179, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "right" - }, - "tooltip": { - "mode": "single" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "log_error_count{namespace=\"$namespace\"}", - "interval": "", - "legendFormat": "WARN, pod: {{pod}}", - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "log_warn_count{namespace=\"$namespace\"}", - "hide": false, - "interval": "", - "legendFormat": "ERROR, pod: {{pod}}", - "refId": "B" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "log_panic_count{namespace=\"$namespace\"}", - "hide": false, - "interval": "", - "legendFormat": "PANIC, pod: {{pod}}", - "refId": "C" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "log_critical_count{namespace=\"$namespace\"}", - "hide": false, - "interval": "", - "legendFormat": "CRITICAL, pod: {{pod}}", - "refId": "D" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "log_fatal_count{namespace=\"$namespace\"}", - "hide": false, - "interval": "", - "legendFormat": "FATAL, pod: {{pod}}", - "refId": "E" - } - ], - "title": "Overall log count by type", - "transparent": true, - "type": "timeseries" - } - ], - "title": "Overall metrics across all CL nodes", - "type": "row" - }, - { - "collapsed": true, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 2 - }, - "id": 169, - "panels": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 4, - "w": 24, - "x": 0, - "y": 3 - }, - "id": 167, - "options": { - "colorMode": "value", - "graphMode": "area", - "justifyMode": "auto", - "orientation": "auto", - "reduceOptions": { - "calcs": ["lastNotNull"], - "fields": "", - "values": false - }, - "textMode": "auto" - }, - "pluginVersion": "8.3.5", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "pipeline_tasks_total_finished{namespace=\"$namespace\", pod=\"$cl_node\"}", - "interval": "", - "legendFormat": "type: {{task_type}}, jobID: {{job_id}}, status: {{status}}", - "refId": "A" - } - ], - "title": "Pipeline tasks", - "transparent": true, - "type": "stat" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 7 - }, - "id": 171, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom" - }, - "tooltip": { - "mode": "single" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "pipeline_task_runs_queued{namespace=\"$namespace\", pod=\"$cl_node\"}", - "interval": "", - "legendFormat": "Tasks", - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "pipeline_runs_queued{namespace=\"$namespace\", pod=\"$cl_node\"}", - "hide": false, - "interval": "", - "legendFormat": "Pipelines", - "refId": "B" - } - ], - "title": "Queued tasks and pipelines", - "transparent": true, - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "Pipeline avg time to completion", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisLabel": "Duration, ms", - "axisPlacement": "left", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 7 - }, - "id": 173, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom" - }, - "tooltip": { - "mode": "single" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "pipeline_run_total_time_to_completion{namespace=\"$namespace\", pod=\"$cl_node\"} * 1e-6", - "interval": "", - "legendFormat": "jobID: {{job_id}}", - "refId": "A" - } - ], - "title": "Pipeline avg time to completion", - "transparent": true, - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "Pipeline fetch avg bytes", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisLabel": "Size, Bytes", - "axisPlacement": "left", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 15 - }, - "id": 177, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom" - }, - "tooltip": { - "mode": "single" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "pipeline_task_http_response_body_size{namespace=\"$namespace\", pod=\"$cl_node\"}", - "interval": "", - "legendFormat": "Task type: {{pipeline_task_spec_id}}", - "refId": "A" - } - ], - "title": "Pipeline fetch avg bytes", - "transparent": true, - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "Task execution time by type", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisLabel": "Duration, ms", - "axisPlacement": "left", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 15 - }, - "id": 175, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom" - }, - "tooltip": { - "mode": "single" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "pipeline_task_execution_time{namespace=\"$namespace\", pod=\"$cl_node\"} * 1e-6", - "interval": "", - "legendFormat": "type: {{task_type}}", - "refId": "A" - } - ], - "title": "Task execution time by type", - "transparent": true, - "type": "timeseries" - } - ], - "title": "Pipeline tasks ($cl_node)", - "type": "row" - }, - { - "collapsed": true, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 3 - }, - "id": 147, - "panels": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 4 - }, - "id": 159, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom" - }, - "tooltip": { - "mode": "single" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "rate(evm_pool_rpc_node_polls_success{namespace=\"$namespace\", pod=\"$cl_node\"} [2m])", - "interval": "", - "legendFormat": "", - "refId": "A" - } - ], - "title": "EVM node polls", - "transparent": true, - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "RPC calls hist", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 4 - }, - "id": 157, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom" - }, - "tooltip": { - "mode": "single" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "histogram_quantile(0.95, sum(rate(evm_pool_rpc_node_rpc_call_time_bucket{pod=\"$cl_node\", rpcCallName=\"CallContext\"}[2m])) by (le)) * 1e-6", - "interval": "", - "legendFormat": "CallContext - 95", - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "histogram_quantile(0.5, sum(rate(evm_pool_rpc_node_rpc_call_time_bucket{pod=\"$cl_node\", rpcCallName=\"CallContext\"}[2m])) by (le)) * 1e-6", - "hide": false, - "interval": "", - "legendFormat": "CallContext - 50", - "refId": "B" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "histogram_quantile(0.95, sum(rate(evm_pool_rpc_node_rpc_call_time_bucket{rpcCallName=\"BatchCallContext\"}[2m])) by (le)) * 1e-6", - "hide": false, - "interval": "", - "legendFormat": "BatchCallContext - 95", - "refId": "C" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "histogram_quantile(0.5, sum(rate(evm_pool_rpc_node_rpc_call_time_bucket{rpcCallName=\"BatchCallContext\"}[2m])) by (le)) * 1e-6", - "hide": false, - "interval": "", - "legendFormat": "BatchCallContext - 50", - "refId": "D" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "histogram_quantile(0.95, sum(rate(evm_pool_rpc_node_rpc_call_time_bucket{rpcCallName=\"BalanceAt\"}[2m])) by (le)) * 1e-6", - "hide": false, - "interval": "", - "legendFormat": "BalanceAt - 95", - "refId": "E" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "histogram_quantile(0.50, sum(rate(evm_pool_rpc_node_rpc_call_time_bucket{rpcCallName=\"BalanceAt\"}[2m])) by (le)) * 1e-6", - "hide": false, - "interval": "", - "legendFormat": "BalanceAt - 50", - "refId": "F" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "histogram_quantile(0.95, sum(rate(evm_pool_rpc_node_rpc_call_time_bucket{rpcCallName=\"PendingNonceAt\"}[2m])) by (le)) * 1e-6", - "hide": false, - "interval": "", - "legendFormat": "PendingNonceAt - 95", - "refId": "G" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "histogram_quantile(0.50, sum(rate(evm_pool_rpc_node_rpc_call_time_bucket{rpcCallName=\"PendingNonceAt\"}[2m])) by (le)) * 1e-6", - "hide": false, - "interval": "", - "legendFormat": "PendingNonceAt - 50", - "refId": "H" - } - ], - "title": "RPC calls hist", - "transparent": true, - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "RPC node states", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 12 - }, - "id": 153, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom" - }, - "tooltip": { - "mode": "single" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "evm_pool_rpc_node_states{namespace=\"$namespace\", pod=\"$cl_node\"}", - "interval": "", - "legendFormat": "chainId: {{evmChainID}} pod: {{pod}} state: {{state}}", - "refId": "A" - } - ], - "title": "RPC node states", - "transparent": true, - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 12 - }, - "id": 151, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom" - }, - "tooltip": { - "mode": "single" - } - }, - "pluginVersion": "8.3.5", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "evm_pool_rpc_node_num_transitions_to_alive{namespace=\"$namespace\", pod=\"$cl_node\"}", - "interval": "", - "legendFormat": "chainId: {{evmChainID}} pod: {{pod}}", - "refId": "A" - } - ], - "title": "RPC node alive statuses", - "transparent": true, - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "RPC calls total (rate)", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 20 - }, - "id": 145, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom" - }, - "tooltip": { - "mode": "single" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "rate(evm_pool_rpc_node_calls_total{namespace=\"$namespace\", pod=\"$cl_node\"}[2m])", - "interval": "", - "legendFormat": "", - "refId": "A" - } - ], - "title": "RPC calls total (rate)", - "transparent": true, - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 20 - }, - "id": 155, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom" - }, - "tooltip": { - "mode": "single" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "rate(evm_pool_rpc_node_verifies{namespace=\"$namespace\", pod=\"$cl_node\"} [2m])", - "interval": "", - "legendFormat": "Success, chainId: {{evmChainID}} nodeName: {{nodeName }} instance: {{instance}}", - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "rate(evm_pool_rpc_node_verifies_success{namespace=\"$namespace\", pod=\"$cl_node\"} [2m])", - "hide": false, - "interval": "", - "legendFormat": "Total, chainId: {{evmChainID}} nodeName: {{nodeName }} instance: {{instance}}", - "refId": "B" - } - ], - "title": "Total verifications (success/errors)", - "transparent": true, - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "ETH account value", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisLabel": "", - "axisPlacement": "left", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineStyle": { - "fill": "solid" - }, - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 28 - }, - "id": 165, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom" - }, - "tooltip": { - "mode": "single" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": false, - "expr": "eth_balance{namespace=\"$namespace\", pod=\"$cl_node\"}", - "interval": "", - "intervalFactor": 1, - "legendFormat": "account: {{account}}", - "refId": "A" - } - ], - "title": "ETH account value", - "transparent": true, - "type": "timeseries" - } - ], - "title": "EVM CL node metrics ($cl_node)", - "type": "row" - }, - { - "collapsed": true, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 4 - }, - "id": 183, - "panels": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "TXns count (confirmed/unconfirmed)", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 5 - }, - "id": 185, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom" - }, - "tooltip": { - "mode": "single" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "unconfirmed_transactions{namespace=\"$namespace\", pod=\"$cl_node\"}", - "interval": "", - "legendFormat": "Unconfirmed, Pod: {{pod}}", - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "tx_manager_num_confirmed_transactions{namespace=\"$namespace\", pod=\"$cl_node\"}", - "hide": false, - "interval": "", - "legendFormat": "Confirmed, Pod: {{pod}}", - "refId": "B" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "tx_manager_num_successful_transactions{namespace=\"$namespace\", pod=\"$cl_node\"}", - "hide": false, - "interval": "", - "legendFormat": "Successful, Pod: {{pod}}", - "refId": "C" - } - ], - "title": "TXns count (confirmed/unconfirmed)", - "transparent": true, - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisLabel": "Duration, ms", - "axisPlacement": "left", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 5 - }, - "id": 187, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom" - }, - "tooltip": { - "mode": "single" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "histogram_quantile(0.95, sum(rate(tx_manager_time_until_tx_confirmed_bucket [2m])) by (le)) * 1e-6", - "instant": false, - "interval": "", - "legendFormat": "TxConfirmed - 95", - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "histogram_quantile(0.50, sum(rate(tx_manager_time_until_tx_confirmed_bucket [2m])) by (le)) * 1e-6", - "hide": false, - "interval": "", - "legendFormat": "TxConfirmed - 50", - "refId": "B" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "histogram_quantile(0.95, sum(rate(tx_manager_time_until_tx_broadcast_bucket [2m])) by (le)) * 1e-6", - "hide": false, - "interval": "", - "legendFormat": "TxBroadcast -95", - "refId": "C" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "histogram_quantile(0.50, sum(rate(tx_manager_time_until_tx_broadcast_bucket [2m])) by (le)) * 1e-6", - "hide": false, - "interval": "", - "legendFormat": "TxBroadcast -50", - "refId": "D" - } - ], - "title": "TXns times", - "transparent": true, - "type": "timeseries" - } - ], - "title": "TX manager ($cl_node)", - "type": "row" - }, - { - "collapsed": true, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 5 - }, - "id": 35, - "panels": [ - { - "description": "All logs of the Chainlink node", - "gridPos": { - "h": 10, - "w": 12, - "x": 0, - "y": 6 - }, - "id": 33, - "options": { - "dedupStrategy": "none", - "enableLogDetails": true, - "prettifyLogMessage": false, - "showCommonLabels": false, - "showLabels": false, - "showTime": false, - "sortOrder": "Descending", - "wrapLogMessage": false - }, - "pluginVersion": "8.5.0", - "targets": [ - { - "datasource": { - "type": "loki", - "uid": "grafanacloud-logs" - }, - "expr": "{namespace=\"$namespace\", container=\"node\", pod=\"$cl_node\"}", - "queryType": "range", - "refId": "A" - } - ], - "title": "Chainlink Node Logs", - "transparent": true, - "type": "logs" - }, - { - "description": "All [ERROR] logs from the Chainlink node.", - "gridPos": { - "h": 10, - "w": 12, - "x": 12, - "y": 6 - }, - "id": 38, - "options": { - "dedupStrategy": "none", - "enableLogDetails": true, - "prettifyLogMessage": false, - "showCommonLabels": false, - "showLabels": false, - "showTime": false, - "sortOrder": "Descending", - "wrapLogMessage": false - }, - "pluginVersion": "8.5.0", - "targets": [ - { - "datasource": { - "type": "loki", - "uid": "grafanacloud-logs" - }, - "expr": "{namespace=\"$namespace\", container=\"node\", pod=\"$cl_node\"} | json | level=~\"error|crit\"", - "queryType": "range", - "refId": "A" - } - ], - "title": "Chainlink Node Errors", - "transparent": true, - "type": "logs" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "Chainlink CPU usage and limit", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisLabel": "CPU Power", - "axisPlacement": "left", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 5, - "gradientMode": "opacity", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineStyle": { - "fill": "solid" - }, - "lineWidth": 2, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "min": 0, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 6, - "x": 0, - "y": 16 - }, - "id": 41, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "kube_pod_container_resource_limits{container=\"node\", pod=\"$cl_node\", resource=\"cpu\"}", - "interval": "", - "legendFormat": "", - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "container_cpu_load_average_10s{namespace=\"$namespace\", container=\"node\", pod=\"$cl_node\"}", - "hide": false, - "interval": "", - "legendFormat": "", - "refId": "B" - } - ], - "title": "CPU", - "transparent": true, - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "Chainlink RAM usage and limit", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisLabel": "MiB", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 5, - "gradientMode": "opacity", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 2, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "min": 0, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 6, - "x": 6, - "y": 16 - }, - "id": 42, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "kube_pod_container_resource_limits{container=\"node\", pod=\"$cl_node\", resource=\"memory\"} / 1024 / 1024", - "interval": "", - "legendFormat": "Limits, container: {{container}} pod: {{pod}}", - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "container_memory_usage_bytes{container=\"node\", pod=\"$cl_node\"} / 1024 / 1024", - "hide": false, - "interval": "", - "legendFormat": "Used, container: {{container}} pod: {{pod}}", - "refId": "B" - } - ], - "title": "RAM", - "transparent": true, - "type": "timeseries" - }, - { - "description": "All [WARN] logs from the Chainlink node.", - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 16 - }, - "id": 102, - "options": { - "dedupStrategy": "none", - "enableLogDetails": true, - "prettifyLogMessage": false, - "showCommonLabels": false, - "showLabels": false, - "showTime": false, - "sortOrder": "Descending", - "wrapLogMessage": false - }, - "pluginVersion": "8.5.0", - "targets": [ - { - "datasource": { - "type": "loki", - "uid": "grafanacloud-logs" - }, - "expr": "{namespace=\"$namespace\", container=\"node\", pod=\"$cl_node\"} | json | level=~\"warn\" | msg!=\"Disk space is not enough to log into disk any longer, required disk space\"", - "queryType": "range", - "refId": "A" - } - ], - "title": "Chainlink Node Warnings", - "transparent": true, - "type": "logs" - } - ], - "repeat": "cl_node", - "title": "CL node metrics ($cl_node)", - "type": "row" - }, - { - "collapsed": true, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 6 - }, - "id": 104, - "panels": [ - { - "gridPos": { - "h": 12, - "w": 18, - "x": 0, - "y": 7 - }, - "id": 106, - "options": { - "dedupStrategy": "none", - "enableLogDetails": true, - "prettifyLogMessage": false, - "showCommonLabels": false, - "showLabels": false, - "showTime": false, - "sortOrder": "Descending", - "wrapLogMessage": false - }, - "pluginVersion": "8.5.5", - "targets": [ - { - "datasource": { - "type": "loki", - "uid": "grafanacloud-logs" - }, - "expr": "{namespace=\"$namespace\", container=~\"geth-network|starknetdev\", pod=\"$geth_node\"}", - "refId": "A" - } - ], - "title": "Geth Logs", - "transparent": true, - "type": "logs" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "Geth CPU usage and limit", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisLabel": "CPU Power", - "axisPlacement": "left", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 5, - "gradientMode": "opacity", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineStyle": { - "fill": "solid" - }, - "lineWidth": 2, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "min": 0, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 6, - "w": 6, - "x": 18, - "y": 7 - }, - "id": 107, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "kube_pod_container_resource_limits{exported_namespace=\"$namespace\", container=\"geth-network\", resource=\"cpu\"}", - "interval": "", - "legendFormat": "", - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "container_cpu_load_average_10s{namespace=\"$namespace\", container=~\"geth-network|starknetdev\"}", - "hide": false, - "interval": "", - "legendFormat": "", - "refId": "B" - } - ], - "title": "Geth CPU", - "transparent": true, - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "Geth RAM usage and limit", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisLabel": "MiB", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 5, - "gradientMode": "opacity", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 2, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "min": 0, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 6, - "w": 6, - "x": 18, - "y": 13 - }, - "id": 108, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "kube_pod_container_resource_limits{exported_namespace=\"$namespace\", container=~\"geth-network|starknetdev\", resource=\"memory\"} / 1024 / 1024", - "interval": "", - "legendFormat": "", - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "container_memory_usage_bytes{namespace=\"$namespace\", container=~\"geth-network|starknetdev\"} / 1024 / 1024", - "hide": false, - "interval": "", - "legendFormat": "", - "refId": "B" - } - ], - "title": "Geth RAM", - "transparent": true, - "type": "timeseries" - } - ], - "repeat": "geth_node", - "title": "Simulated network metrics ($geth_node)", - "type": "row" - }, - { - "collapsed": true, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 7 - }, - "id": 76, - "panels": [ - { - "description": "Logs of the mockserver", - "gridPos": { - "h": 12, - "w": 18, - "x": 0, - "y": 8 - }, - "id": 70, - "options": { - "dedupStrategy": "none", - "enableLogDetails": true, - "prettifyLogMessage": false, - "showCommonLabels": false, - "showLabels": false, - "showTime": true, - "sortOrder": "Descending", - "wrapLogMessage": false - }, - "pluginVersion": "8.5.0", - "targets": [ - { - "datasource": { - "type": "loki", - "uid": "grafanacloud-logs" - }, - "expr": "{namespace=\"$namespace\", container=\"mockserver\"}", - "refId": "A" - } - ], - "title": "Mock Server Logs", - "transparent": true, - "type": "logs" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "Mock Server CPU usage and limit", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisLabel": "CPU Power", - "axisPlacement": "left", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 5, - "gradientMode": "opacity", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineStyle": { - "fill": "solid" - }, - "lineWidth": 2, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "min": 0, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 6, - "w": 6, - "x": 18, - "y": 8 - }, - "id": 71, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "kube_pod_container_resource_limits{exported_namespace=\"$namespace\", container=\"mockserver\", resource=\"cpu\"}", - "interval": "", - "legendFormat": "", - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "container_cpu_load_average_10s{namespace=\"$namespace\", container=\"mockserver\"}", - "hide": false, - "interval": "", - "legendFormat": "", - "refId": "B" - } - ], - "title": "Mock Server CPU", - "transparent": true, - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "Mock Server RAM usage and limit", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisLabel": "MiB", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 5, - "gradientMode": "opacity", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 2, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 6, - "w": 6, - "x": 18, - "y": 14 - }, - "id": 72, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "kube_pod_container_resource_limits{exported_namespace=\"$namespace\", container=\"mockserver\", resource=\"memory\"} / 1024 / 1024", - "interval": "", - "legendFormat": "", - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "container_memory_usage_bytes{namespace=\"$namespace\", container=\"mockserver\"} / 1024 / 1024", - "hide": false, - "interval": "", - "legendFormat": "", - "refId": "B" - } - ], - "title": "Mock Server RAM", - "transparent": true, - "type": "timeseries" - } - ], - "title": "Mock Server", - "type": "row" - }, - { - "collapsed": true, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 8 - }, - "id": 74, - "panels": [ - { - "description": "Logs of the instance actually running the tests", - "gridPos": { - "h": 12, - "w": 18, - "x": 0, - "y": 9 - }, - "id": 36, - "options": { - "dedupStrategy": "none", - "enableLogDetails": true, - "prettifyLogMessage": false, - "showCommonLabels": false, - "showLabels": false, - "showTime": false, - "sortOrder": "Descending", - "wrapLogMessage": false - }, - "pluginVersion": "8.5.0", - "targets": [ - { - "datasource": { - "type": "loki", - "uid": "grafanacloud-logs" - }, - "expr": "{namespace=\"$namespace\", container=\"remote-test-runner\"}", - "refId": "A" - } - ], - "title": "Test Runner Logs", - "transparent": true, - "type": "logs" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "Test Runner CPU usage and limit", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisLabel": "CPU Power", - "axisPlacement": "left", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 5, - "gradientMode": "opacity", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineStyle": { - "fill": "solid" - }, - "lineWidth": 2, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "min": 0, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 6, - "w": 6, - "x": 18, - "y": 9 - }, - "id": 43, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "kube_pod_container_resource_limits{exported_namespace=\"$namespace\", container=\"remote-test-runner\", resource=\"cpu\"}", - "interval": "", - "legendFormat": "", - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "container_cpu_load_average_10s{namespace=\"$namespace\", container=\"remote-test-runner\"}", - "hide": false, - "interval": "", - "legendFormat": "", - "refId": "B" - } - ], - "title": "Runner CPU", - "transparent": true, - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "Test Runner RAM usage and limit", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisLabel": "MiB", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 5, - "gradientMode": "opacity", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 2, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "min": 0, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 6, - "w": 6, - "x": 18, - "y": 15 - }, - "id": 44, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "kube_pod_container_resource_limits{exported_namespace=\"$namespace\", container=\"remote-test-runner\", resource=\"memory\"} / 1024 / 1024", - "interval": "", - "legendFormat": "", - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "container_memory_usage_bytes{namespace=\"$namespace\", container=\"remote-test-runner\"} / 1024 / 1024", - "hide": false, - "interval": "", - "legendFormat": "", - "refId": "B" - } - ], - "title": "Runner RAM", - "transparent": true, - "type": "timeseries" - }, - { - "description": "Errors and Warnings found in Test Runner", - "gridPos": { - "h": 5, - "w": 8, - "x": 0, - "y": 21 - }, - "id": 139, - "options": { - "dedupStrategy": "none", - "enableLogDetails": true, - "prettifyLogMessage": false, - "showCommonLabels": false, - "showLabels": false, - "showTime": false, - "sortOrder": "Descending", - "wrapLogMessage": false - }, - "pluginVersion": "8.5.0", - "targets": [ - { - "datasource": { - "type": "loki", - "uid": "grafanacloud-logs" - }, - "expr": "{namespace=\"$namespace\", container=\"remote-test-runner\"} |~ \"WRN|ERR\"", - "refId": "A" - } - ], - "title": "Test Runner Errors and Warnings", - "transparent": true, - "type": "logs" - }, - { - "description": "Info logs", - "gridPos": { - "h": 5, - "w": 8, - "x": 8, - "y": 21 - }, - "id": 140, - "options": { - "dedupStrategy": "none", - "enableLogDetails": true, - "prettifyLogMessage": false, - "showCommonLabels": false, - "showLabels": false, - "showTime": false, - "sortOrder": "Descending", - "wrapLogMessage": false - }, - "pluginVersion": "8.5.0", - "targets": [ - { - "datasource": { - "type": "loki", - "uid": "grafanacloud-logs" - }, - "expr": "{namespace=\"$namespace\", container=\"remote-test-runner\"} |= \"INF\"", - "refId": "A" - } - ], - "title": "Test Runner Info", - "transparent": true, - "type": "logs" - }, - { - "description": "Debugs", - "gridPos": { - "h": 5, - "w": 8, - "x": 16, - "y": 21 - }, - "id": 141, - "options": { - "dedupStrategy": "none", - "enableLogDetails": true, - "prettifyLogMessage": false, - "showCommonLabels": false, - "showLabels": false, - "showTime": false, - "sortOrder": "Descending", - "wrapLogMessage": false - }, - "pluginVersion": "8.5.0", - "targets": [ - { - "datasource": { - "type": "loki", - "uid": "grafanacloud-logs" - }, - "expr": "{namespace=\"$namespace\", container=\"remote-test-runner\"} |~ \"DBG\"", - "refId": "A" - } - ], - "title": "Test Runner Debugs", - "transparent": true, - "type": "logs" - } - ], - "title": "Test runner", - "type": "row" - } - ], - "refresh": "5s", - "schemaVersion": 34, - "style": "dark", - "tags": ["tests"], - "templating": { - "list": [ - { - "current": { - "selected": false, - "text": "chainlink-test-env-3735f", - "value": "chainlink-test-env-3735f" - }, - "definition": "label_values(namespace)", - "description": "Namespace", - "hide": 0, - "includeAll": false, - "label": "Namespace", - "multi": false, - "name": "namespace", - "options": [], - "query": "label_values(namespace)", - "refresh": 1, - "regex": "chainlink-.*|.*-soak-.*|.*performance-.*|.*-chaos-.*", - "skipUrlSync": false, - "sort": 0, - "type": "query" - }, - { - "current": { - "selected": true, - "text": ["chainlink-0-98744888d-r9n6r"], - "value": ["chainlink-0-98744888d-r9n6r"] - }, - "definition": "label_values({namespace=\"$namespace\"}, pod)", - "description": "The specific Chainlink node to get insight into", - "hide": 0, - "includeAll": false, - "label": "Chainlink Node", - "multi": true, - "name": "cl_node", - "options": [], - "query": "label_values({namespace=\"$namespace\"}, pod)", - "refresh": 1, - "regex": "chainlink-.*", - "skipUrlSync": false, - "sort": 0, - "type": "query" - }, - { - "current": { - "selected": false, - "text": "geth-6469b5b5f8-smd2z", - "value": "geth-6469b5b5f8-smd2z" - }, - "definition": "label_values({namespace=\"$namespace\"}, pod)", - "description": "If launched, a simulated instance of Geth", - "hide": 0, - "includeAll": false, - "label": "Simulated Geth Node", - "multi": false, - "name": "geth_node", - "options": [], - "query": "label_values({namespace=\"$namespace\"}, pod)", - "refresh": 1, - "regex": "geth-|starknet.*", - "skipUrlSync": false, - "sort": 0, - "type": "query" - } - ] - }, - "time": { - "from": "now-30m", - "to": "now" - }, - "timepicker": {}, - "timezone": "", - "title": "Chainlink Testing Insights", - "uid": "AFATC9A7k", - "version": 1, - "weekStart": "" -} diff --git a/lib/k8s/grafana/values.yml b/lib/k8s/grafana/values.yml deleted file mode 100644 index 99c5569ea..000000000 --- a/lib/k8s/grafana/values.yml +++ /dev/null @@ -1,20 +0,0 @@ -grafana: - adminUser: admin - adminPassword: sdkfh26!@bHasdZ2 - dashboardProviders: - dashboardproviders.yaml: - apiVersion: 1 - providers: - - name: 'default' - orgId: 1 - folder: '' - type: file - disableDeletion: false - editable: true - options: - path: /var/lib/grafana/dashboards/default - dashboards: - default: - cl_insights: - json: | - {"annotations":{"list":[{"builtIn":1,"datasource":{"type":"datasource","uid":"grafana"},"enable":true,"hide":true,"iconColor":"rgba(0, 211, 255, 1)","name":"Annotations & Alerts","target":{"limit":100,"matchAny":false,"tags":[],"type":"dashboard"},"type":"dashboard"}]},"description":"A look at the components of Chainlink Integration tests","editable":true,"fiscalYearStartMonth":0,"graphTooltip":0,"iteration":1662412920215,"links":[],"liveNow":false,"panels":[{"collapsed":true,"gridPos":{"h":1,"w":24,"x":0,"y":0},"id":161,"panels":[{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"description":"Components health","fieldConfig":{"defaults":{"color":{"mode":"thresholds"},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]}},"overrides":[]},"gridPos":{"h":20,"w":24,"x":0,"y":1},"id":163,"options":{"colorMode":"value","graphMode":"area","justifyMode":"auto","orientation":"auto","reduceOptions":{"calcs":["last"],"fields":"","values":false},"text":{"titleSize":14,"valueSize":14},"textMode":"name"},"pluginVersion":"8.3.5","targets":[{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"health{namespace=\"$namespace\", pod=\"$cl_node\"}","interval":"","legendFormat":"service: {{service_id}}","refId":"A"}],"title":"Components health","transparent":true,"type":"stat"}],"title":"Components health","type":"row"},{"collapsed":true,"gridPos":{"h":1,"w":24,"x":0,"y":1},"id":181,"panels":[{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"description":"Overall log count by type","fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":0,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]}},"overrides":[]},"gridPos":{"h":8,"w":12,"x":0,"y":2},"id":179,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"right"},"tooltip":{"mode":"single"}},"targets":[{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"log_error_count{namespace=\"$namespace\"}","interval":"","legendFormat":"WARN, pod: {{pod}}","refId":"A"},{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"log_warn_count{namespace=\"$namespace\"}","hide":false,"interval":"","legendFormat":"ERROR, pod: {{pod}}","refId":"B"},{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"log_panic_count{namespace=\"$namespace\"}","hide":false,"interval":"","legendFormat":"PANIC, pod: {{pod}}","refId":"C"},{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"log_critical_count{namespace=\"$namespace\"}","hide":false,"interval":"","legendFormat":"CRITICAL, pod: {{pod}}","refId":"D"},{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"log_fatal_count{namespace=\"$namespace\"}","hide":false,"interval":"","legendFormat":"FATAL, pod: {{pod}}","refId":"E"}],"title":"Overall log count by type","transparent":true,"type":"timeseries"}],"title":"Overall metrics across all CL nodes","type":"row"},{"collapsed":true,"gridPos":{"h":1,"w":24,"x":0,"y":2},"id":169,"panels":[{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"fieldConfig":{"defaults":{"color":{"mode":"thresholds"},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]}},"overrides":[]},"gridPos":{"h":4,"w":24,"x":0,"y":3},"id":167,"options":{"colorMode":"value","graphMode":"area","justifyMode":"auto","orientation":"auto","reduceOptions":{"calcs":["lastNotNull"],"fields":"","values":false},"textMode":"auto"},"pluginVersion":"8.3.5","targets":[{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"pipeline_tasks_total_finished{namespace=\"$namespace\", pod=\"$cl_node\"}","interval":"","legendFormat":"type: {{task_type}}, jobID: {{job_id}}, status: {{status}}","refId":"A"}],"title":"Pipeline tasks","transparent":true,"type":"stat"},{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":0,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]}},"overrides":[]},"gridPos":{"h":8,"w":12,"x":0,"y":7},"id":171,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom"},"tooltip":{"mode":"single"}},"targets":[{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"pipeline_task_runs_queued{namespace=\"$namespace\", pod=\"$cl_node\"}","interval":"","legendFormat":"Tasks","refId":"A"},{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"pipeline_runs_queued{namespace=\"$namespace\", pod=\"$cl_node\"}","hide":false,"interval":"","legendFormat":"Pipelines","refId":"B"}],"title":"Queued tasks and pipelines","transparent":true,"type":"timeseries"},{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"description":"Pipeline avg time to completion","fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisLabel":"Duration, ms","axisPlacement":"left","barAlignment":0,"drawStyle":"line","fillOpacity":0,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]}},"overrides":[]},"gridPos":{"h":8,"w":12,"x":12,"y":7},"id":173,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom"},"tooltip":{"mode":"single"}},"targets":[{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"pipeline_run_total_time_to_completion{namespace=\"$namespace\", pod=\"$cl_node\"} * 1e-6","interval":"","legendFormat":"jobID: {{job_id}}","refId":"A"}],"title":"Pipeline avg time to completion","transparent":true,"type":"timeseries"},{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"description":"Pipeline fetch avg bytes","fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisLabel":"Size, Bytes","axisPlacement":"left","barAlignment":0,"drawStyle":"line","fillOpacity":0,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]}},"overrides":[]},"gridPos":{"h":8,"w":12,"x":0,"y":15},"id":177,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom"},"tooltip":{"mode":"single"}},"targets":[{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"pipeline_task_http_response_body_size{namespace=\"$namespace\", pod=\"$cl_node\"}","interval":"","legendFormat":"Task type: {{pipeline_task_spec_id}}","refId":"A"}],"title":"Pipeline fetch avg bytes","transparent":true,"type":"timeseries"},{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"description":"Task execution time by type","fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisLabel":"Duration, ms","axisPlacement":"left","barAlignment":0,"drawStyle":"line","fillOpacity":0,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]}},"overrides":[]},"gridPos":{"h":8,"w":12,"x":12,"y":15},"id":175,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom"},"tooltip":{"mode":"single"}},"targets":[{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"pipeline_task_execution_time{namespace=\"$namespace\", pod=\"$cl_node\"} * 1e-6","interval":"","legendFormat":"type: {{task_type}}","refId":"A"}],"title":"Task execution time by type","transparent":true,"type":"timeseries"}],"title":"Pipeline tasks ($cl_node)","type":"row"},{"collapsed":true,"gridPos":{"h":1,"w":24,"x":0,"y":3},"id":147,"panels":[{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":0,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]}},"overrides":[]},"gridPos":{"h":8,"w":12,"x":0,"y":4},"id":159,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom"},"tooltip":{"mode":"single"}},"targets":[{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"rate(evm_pool_rpc_node_polls_success{namespace=\"$namespace\", pod=\"$cl_node\"} [2m])","interval":"","legendFormat":"","refId":"A"}],"title":"EVM node polls","transparent":true,"type":"timeseries"},{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"description":"RPC calls hist","fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":0,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]}},"overrides":[]},"gridPos":{"h":8,"w":12,"x":12,"y":4},"id":157,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom"},"tooltip":{"mode":"single"}},"targets":[{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"histogram_quantile(0.95, sum(rate(evm_pool_rpc_node_rpc_call_time_bucket{pod=\"$cl_node\", rpcCallName=\"CallContext\"}[2m])) by (le)) * 1e-6","interval":"","legendFormat":"CallContext - 95","refId":"A"},{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"histogram_quantile(0.5, sum(rate(evm_pool_rpc_node_rpc_call_time_bucket{pod=\"$cl_node\", rpcCallName=\"CallContext\"}[2m])) by (le)) * 1e-6","hide":false,"interval":"","legendFormat":"CallContext - 50","refId":"B"},{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"histogram_quantile(0.95, sum(rate(evm_pool_rpc_node_rpc_call_time_bucket{rpcCallName=\"BatchCallContext\"}[2m])) by (le)) * 1e-6","hide":false,"interval":"","legendFormat":"BatchCallContext - 95","refId":"C"},{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"histogram_quantile(0.5, sum(rate(evm_pool_rpc_node_rpc_call_time_bucket{rpcCallName=\"BatchCallContext\"}[2m])) by (le)) * 1e-6","hide":false,"interval":"","legendFormat":"BatchCallContext - 50","refId":"D"},{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"histogram_quantile(0.95, sum(rate(evm_pool_rpc_node_rpc_call_time_bucket{rpcCallName=\"BalanceAt\"}[2m])) by (le)) * 1e-6","hide":false,"interval":"","legendFormat":"BalanceAt - 95","refId":"E"},{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"histogram_quantile(0.50, sum(rate(evm_pool_rpc_node_rpc_call_time_bucket{rpcCallName=\"BalanceAt\"}[2m])) by (le)) * 1e-6","hide":false,"interval":"","legendFormat":"BalanceAt - 50","refId":"F"},{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"histogram_quantile(0.95, sum(rate(evm_pool_rpc_node_rpc_call_time_bucket{rpcCallName=\"PendingNonceAt\"}[2m])) by (le)) * 1e-6","hide":false,"interval":"","legendFormat":"PendingNonceAt - 95","refId":"G"},{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"histogram_quantile(0.50, sum(rate(evm_pool_rpc_node_rpc_call_time_bucket{rpcCallName=\"PendingNonceAt\"}[2m])) by (le)) * 1e-6","hide":false,"interval":"","legendFormat":"PendingNonceAt - 50","refId":"H"}],"title":"RPC calls hist","transparent":true,"type":"timeseries"},{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"description":"RPC node states","fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":0,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]}},"overrides":[]},"gridPos":{"h":8,"w":12,"x":0,"y":12},"id":153,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom"},"tooltip":{"mode":"single"}},"targets":[{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"evm_pool_rpc_node_states{namespace=\"$namespace\", pod=\"$cl_node\"}","interval":"","legendFormat":"chainId: {{evmChainID}} pod: {{pod}} state: {{state}}","refId":"A"}],"title":"RPC node states","transparent":true,"type":"timeseries"},{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":0,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]}},"overrides":[]},"gridPos":{"h":8,"w":12,"x":12,"y":12},"id":151,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom"},"tooltip":{"mode":"single"}},"pluginVersion":"8.3.5","targets":[{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"evm_pool_rpc_node_num_transitions_to_alive{namespace=\"$namespace\", pod=\"$cl_node\"}","interval":"","legendFormat":"chainId: {{evmChainID}} pod: {{pod}}","refId":"A"}],"title":"RPC node alive statuses","transparent":true,"type":"timeseries"},{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"description":"RPC calls total (rate)","fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":0,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]}},"overrides":[]},"gridPos":{"h":8,"w":12,"x":0,"y":20},"id":145,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom"},"tooltip":{"mode":"single"}},"targets":[{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"rate(evm_pool_rpc_node_calls_total{namespace=\"$namespace\", pod=\"$cl_node\"}[2m])","interval":"","legendFormat":"","refId":"A"}],"title":"RPC calls total (rate)","transparent":true,"type":"timeseries"},{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":0,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]}},"overrides":[]},"gridPos":{"h":8,"w":12,"x":12,"y":20},"id":155,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom"},"tooltip":{"mode":"single"}},"targets":[{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"rate(evm_pool_rpc_node_verifies{namespace=\"$namespace\", pod=\"$cl_node\"} [2m])","interval":"","legendFormat":"Success, chainId: {{evmChainID}} nodeName: {{nodeName }} instance: {{instance}}","refId":"A"},{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"rate(evm_pool_rpc_node_verifies_success{namespace=\"$namespace\", pod=\"$cl_node\"} [2m])","hide":false,"interval":"","legendFormat":"Total, chainId: {{evmChainID}} nodeName: {{nodeName }} instance: {{instance}}","refId":"B"}],"title":"Total verifications (success/errors)","transparent":true,"type":"timeseries"},{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"description":"ETH account value","fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisLabel":"","axisPlacement":"left","barAlignment":0,"drawStyle":"line","fillOpacity":0,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"lineInterpolation":"linear","lineStyle":{"fill":"solid"},"lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]}},"overrides":[]},"gridPos":{"h":8,"w":12,"x":0,"y":28},"id":165,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom"},"tooltip":{"mode":"single"}},"targets":[{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":false,"expr":"eth_balance{namespace=\"$namespace\", pod=\"$cl_node\"}","interval":"","intervalFactor":1,"legendFormat":"account: {{account}}","refId":"A"}],"title":"ETH account value","transparent":true,"type":"timeseries"}],"title":"EVM CL node metrics ($cl_node)","type":"row"},{"collapsed":true,"gridPos":{"h":1,"w":24,"x":0,"y":4},"id":183,"panels":[{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"description":"TXns count (confirmed/unconfirmed)","fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":0,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]}},"overrides":[]},"gridPos":{"h":8,"w":12,"x":0,"y":5},"id":185,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom"},"tooltip":{"mode":"single"}},"targets":[{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"unconfirmed_transactions{namespace=\"$namespace\", pod=\"$cl_node\"}","interval":"","legendFormat":"Unconfirmed, Pod: {{pod}}","refId":"A"},{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"tx_manager_num_confirmed_transactions{namespace=\"$namespace\", pod=\"$cl_node\"}","hide":false,"interval":"","legendFormat":"Confirmed, Pod: {{pod}}","refId":"B"},{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"tx_manager_num_successful_transactions{namespace=\"$namespace\", pod=\"$cl_node\"}","hide":false,"interval":"","legendFormat":"Successful, Pod: {{pod}}","refId":"C"}],"title":"TXns count (confirmed/unconfirmed)","transparent":true,"type":"timeseries"},{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisLabel":"Duration, ms","axisPlacement":"left","barAlignment":0,"drawStyle":"line","fillOpacity":0,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]}},"overrides":[]},"gridPos":{"h":8,"w":12,"x":12,"y":5},"id":187,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom"},"tooltip":{"mode":"single"}},"targets":[{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"histogram_quantile(0.95, sum(rate(tx_manager_time_until_tx_confirmed_bucket [2m])) by (le)) * 1e-6","instant":false,"interval":"","legendFormat":"TxConfirmed - 95","refId":"A"},{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"histogram_quantile(0.50, sum(rate(tx_manager_time_until_tx_confirmed_bucket [2m])) by (le)) * 1e-6","hide":false,"interval":"","legendFormat":"TxConfirmed - 50","refId":"B"},{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"histogram_quantile(0.95, sum(rate(tx_manager_time_until_tx_broadcast_bucket [2m])) by (le)) * 1e-6","hide":false,"interval":"","legendFormat":"TxBroadcast -95","refId":"C"},{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"histogram_quantile(0.50, sum(rate(tx_manager_time_until_tx_broadcast_bucket [2m])) by (le)) * 1e-6","hide":false,"interval":"","legendFormat":"TxBroadcast -50","refId":"D"}],"title":"TXns times","transparent":true,"type":"timeseries"}],"title":"TX manager ($cl_node)","type":"row"},{"collapsed":true,"gridPos":{"h":1,"w":24,"x":0,"y":5},"id":35,"panels":[{"description":"All logs of the Chainlink node","gridPos":{"h":10,"w":12,"x":0,"y":6},"id":33,"options":{"dedupStrategy":"none","enableLogDetails":true,"prettifyLogMessage":false,"showCommonLabels":false,"showLabels":false,"showTime":false,"sortOrder":"Descending","wrapLogMessage":false},"pluginVersion":"8.5.0","targets":[{"datasource":{"type":"loki","uid":"grafanacloud-logs"},"expr":"{namespace=\"$namespace\", container=\"node\", pod=\"$cl_node\"}","queryType":"range","refId":"A"}],"title":"Chainlink Node Logs","transparent":true,"type":"logs"},{"description":"All [ERROR] logs from the Chainlink node.","gridPos":{"h":10,"w":12,"x":12,"y":6},"id":38,"options":{"dedupStrategy":"none","enableLogDetails":true,"prettifyLogMessage":false,"showCommonLabels":false,"showLabels":false,"showTime":false,"sortOrder":"Descending","wrapLogMessage":false},"pluginVersion":"8.5.0","targets":[{"datasource":{"type":"loki","uid":"grafanacloud-logs"},"expr":"{namespace=\"$namespace\", container=\"node\", pod=\"$cl_node\"} | json | level=~\"error|crit\"","queryType":"range","refId":"A"}],"title":"Chainlink Node Errors","transparent":true,"type":"logs"},{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"description":"Chainlink CPU usage and limit","fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisLabel":"CPU Power","axisPlacement":"left","barAlignment":0,"drawStyle":"line","fillOpacity":5,"gradientMode":"opacity","hideFrom":{"legend":false,"tooltip":false,"viz":false},"lineInterpolation":"linear","lineStyle":{"fill":"solid"},"lineWidth":2,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]}},"overrides":[]},"gridPos":{"h":8,"w":6,"x":0,"y":16},"id":41,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom","showLegend":true},"tooltip":{"mode":"single","sort":"none"}},"targets":[{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"kube_pod_container_resource_limits{container=\"node\", pod=\"$cl_node\", resource=\"cpu\"}","interval":"","legendFormat":"","refId":"A"},{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"container_cpu_load_average_10s{namespace=\"$namespace\", container=\"node\", pod=\"$cl_node\"}","hide":false,"interval":"","legendFormat":"","refId":"B"}],"title":"CPU","transparent":true,"type":"timeseries"},{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"description":"Chainlink RAM usage and limit","fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisLabel":"MiB","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":5,"gradientMode":"opacity","hideFrom":{"legend":false,"tooltip":false,"viz":false},"lineInterpolation":"linear","lineWidth":2,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]}},"overrides":[]},"gridPos":{"h":8,"w":6,"x":6,"y":16},"id":42,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom","showLegend":true},"tooltip":{"mode":"single","sort":"none"}},"targets":[{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"kube_pod_container_resource_limits{container=\"node\", pod=\"$cl_node\", resource=\"memory\"} / 1024 / 1024","interval":"","legendFormat":"Limits, container: {{container}} pod: {{pod}}","refId":"A"},{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"container_memory_usage_bytes{container=\"node\", pod=\"$cl_node\"} / 1024 / 1024","hide":false,"interval":"","legendFormat":"Used, container: {{container}} pod: {{pod}}","refId":"B"}],"title":"RAM","transparent":true,"type":"timeseries"},{"description":"All [WARN] logs from the Chainlink node.","gridPos":{"h":8,"w":12,"x":12,"y":16},"id":102,"options":{"dedupStrategy":"none","enableLogDetails":true,"prettifyLogMessage":false,"showCommonLabels":false,"showLabels":false,"showTime":false,"sortOrder":"Descending","wrapLogMessage":false},"pluginVersion":"8.5.0","targets":[{"datasource":{"type":"loki","uid":"grafanacloud-logs"},"expr":"{namespace=\"$namespace\", container=\"node\", pod=\"$cl_node\"} | json | level=~\"warn\" | msg!=\"Disk space is not enough to log into disk any longer, required disk space\"","queryType":"range","refId":"A"}],"title":"Chainlink Node Warnings","transparent":true,"type":"logs"}],"repeat":"cl_node","title":"CL node metrics ($cl_node)","type":"row"},{"collapsed":true,"gridPos":{"h":1,"w":24,"x":0,"y":6},"id":104,"panels":[{"gridPos":{"h":12,"w":18,"x":0,"y":7},"id":106,"options":{"dedupStrategy":"none","enableLogDetails":true,"prettifyLogMessage":false,"showCommonLabels":false,"showLabels":false,"showTime":false,"sortOrder":"Descending","wrapLogMessage":false},"pluginVersion":"8.5.5","targets":[{"datasource":{"type":"loki","uid":"grafanacloud-logs"},"expr":"{namespace=\"$namespace\", container=~\"geth-network|starknetdev\", pod=\"$geth_node\"}","refId":"A"}],"title":"Geth Logs","transparent":true,"type":"logs"},{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"description":"Geth CPU usage and limit","fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisLabel":"CPU Power","axisPlacement":"left","barAlignment":0,"drawStyle":"line","fillOpacity":5,"gradientMode":"opacity","hideFrom":{"legend":false,"tooltip":false,"viz":false},"lineInterpolation":"linear","lineStyle":{"fill":"solid"},"lineWidth":2,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]}},"overrides":[]},"gridPos":{"h":6,"w":6,"x":18,"y":7},"id":107,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom","showLegend":true},"tooltip":{"mode":"single","sort":"none"}},"targets":[{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"kube_pod_container_resource_limits{exported_namespace=\"$namespace\", container=\"geth-network\", resource=\"cpu\"}","interval":"","legendFormat":"","refId":"A"},{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"container_cpu_load_average_10s{namespace=\"$namespace\", container=~\"geth-network|starknetdev\"}","hide":false,"interval":"","legendFormat":"","refId":"B"}],"title":"Geth CPU","transparent":true,"type":"timeseries"},{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"description":"Geth RAM usage and limit","fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisLabel":"MiB","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":5,"gradientMode":"opacity","hideFrom":{"legend":false,"tooltip":false,"viz":false},"lineInterpolation":"linear","lineWidth":2,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]}},"overrides":[]},"gridPos":{"h":6,"w":6,"x":18,"y":13},"id":108,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom","showLegend":true},"tooltip":{"mode":"single","sort":"none"}},"targets":[{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"kube_pod_container_resource_limits{exported_namespace=\"$namespace\", container=~\"geth-network|starknetdev\", resource=\"memory\"} / 1024 / 1024","interval":"","legendFormat":"","refId":"A"},{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"container_memory_usage_bytes{namespace=\"$namespace\", container=~\"geth-network|starknetdev\"} / 1024 / 1024","hide":false,"interval":"","legendFormat":"","refId":"B"}],"title":"Geth RAM","transparent":true,"type":"timeseries"}],"repeat":"geth_node","title":"Simulated network metrics ($geth_node)","type":"row"},{"collapsed":true,"gridPos":{"h":1,"w":24,"x":0,"y":7},"id":76,"panels":[{"description":"Logs of the mockserver","gridPos":{"h":12,"w":18,"x":0,"y":8},"id":70,"options":{"dedupStrategy":"none","enableLogDetails":true,"prettifyLogMessage":false,"showCommonLabels":false,"showLabels":false,"showTime":true,"sortOrder":"Descending","wrapLogMessage":false},"pluginVersion":"8.5.0","targets":[{"datasource":{"type":"loki","uid":"grafanacloud-logs"},"expr":"{namespace=\"$namespace\", container=\"mockserver\"}","refId":"A"}],"title":"Mock Server Logs","transparent":true,"type":"logs"},{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"description":"Mock Server CPU usage and limit","fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisLabel":"CPU Power","axisPlacement":"left","barAlignment":0,"drawStyle":"line","fillOpacity":5,"gradientMode":"opacity","hideFrom":{"legend":false,"tooltip":false,"viz":false},"lineInterpolation":"linear","lineStyle":{"fill":"solid"},"lineWidth":2,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]}},"overrides":[]},"gridPos":{"h":6,"w":6,"x":18,"y":8},"id":71,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom","showLegend":true},"tooltip":{"mode":"single","sort":"none"}},"targets":[{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"kube_pod_container_resource_limits{exported_namespace=\"$namespace\", container=\"mockserver\", resource=\"cpu\"}","interval":"","legendFormat":"","refId":"A"},{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"container_cpu_load_average_10s{namespace=\"$namespace\", container=\"mockserver\"}","hide":false,"interval":"","legendFormat":"","refId":"B"}],"title":"Mock Server CPU","transparent":true,"type":"timeseries"},{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"description":"Mock Server RAM usage and limit","fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisLabel":"MiB","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":5,"gradientMode":"opacity","hideFrom":{"legend":false,"tooltip":false,"viz":false},"lineInterpolation":"linear","lineWidth":2,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]}},"overrides":[]},"gridPos":{"h":6,"w":6,"x":18,"y":14},"id":72,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom","showLegend":true},"tooltip":{"mode":"single","sort":"none"}},"targets":[{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"kube_pod_container_resource_limits{exported_namespace=\"$namespace\", container=\"mockserver\", resource=\"memory\"} / 1024 / 1024","interval":"","legendFormat":"","refId":"A"},{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"container_memory_usage_bytes{namespace=\"$namespace\", container=\"mockserver\"} / 1024 / 1024","hide":false,"interval":"","legendFormat":"","refId":"B"}],"title":"Mock Server RAM","transparent":true,"type":"timeseries"}],"title":"Mock Server","type":"row"},{"collapsed":true,"gridPos":{"h":1,"w":24,"x":0,"y":8},"id":74,"panels":[{"description":"Logs of the instance actually running the tests","gridPos":{"h":12,"w":18,"x":0,"y":9},"id":36,"options":{"dedupStrategy":"none","enableLogDetails":true,"prettifyLogMessage":false,"showCommonLabels":false,"showLabels":false,"showTime":false,"sortOrder":"Descending","wrapLogMessage":false},"pluginVersion":"8.5.0","targets":[{"datasource":{"type":"loki","uid":"grafanacloud-logs"},"expr":"{namespace=\"$namespace\", container=\"remote-test-runner\"}","refId":"A"}],"title":"Test Runner Logs","transparent":true,"type":"logs"},{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"description":"Test Runner CPU usage and limit","fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisLabel":"CPU Power","axisPlacement":"left","barAlignment":0,"drawStyle":"line","fillOpacity":5,"gradientMode":"opacity","hideFrom":{"legend":false,"tooltip":false,"viz":false},"lineInterpolation":"linear","lineStyle":{"fill":"solid"},"lineWidth":2,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]}},"overrides":[]},"gridPos":{"h":6,"w":6,"x":18,"y":9},"id":43,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom","showLegend":true},"tooltip":{"mode":"single","sort":"none"}},"targets":[{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"kube_pod_container_resource_limits{exported_namespace=\"$namespace\", container=\"remote-test-runner\", resource=\"cpu\"}","interval":"","legendFormat":"","refId":"A"},{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"container_cpu_load_average_10s{namespace=\"$namespace\", container=\"remote-test-runner\"}","hide":false,"interval":"","legendFormat":"","refId":"B"}],"title":"Runner CPU","transparent":true,"type":"timeseries"},{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"description":"Test Runner RAM usage and limit","fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisLabel":"MiB","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":5,"gradientMode":"opacity","hideFrom":{"legend":false,"tooltip":false,"viz":false},"lineInterpolation":"linear","lineWidth":2,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]}},"overrides":[]},"gridPos":{"h":6,"w":6,"x":18,"y":15},"id":44,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom","showLegend":true},"tooltip":{"mode":"single","sort":"none"}},"targets":[{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"kube_pod_container_resource_limits{exported_namespace=\"$namespace\", container=\"remote-test-runner\", resource=\"memory\"} / 1024 / 1024","interval":"","legendFormat":"","refId":"A"},{"datasource":{"type":"prometheus","uid":"PBFA97CFB590B2093"},"exemplar":true,"expr":"container_memory_usage_bytes{namespace=\"$namespace\", container=\"remote-test-runner\"} / 1024 / 1024","hide":false,"interval":"","legendFormat":"","refId":"B"}],"title":"Runner RAM","transparent":true,"type":"timeseries"},{"description":"Errors and Warnings found in Test Runner","gridPos":{"h":5,"w":8,"x":0,"y":21},"id":139,"options":{"dedupStrategy":"none","enableLogDetails":true,"prettifyLogMessage":false,"showCommonLabels":false,"showLabels":false,"showTime":false,"sortOrder":"Descending","wrapLogMessage":false},"pluginVersion":"8.5.0","targets":[{"datasource":{"type":"loki","uid":"grafanacloud-logs"},"expr":"{namespace=\"$namespace\", container=\"remote-test-runner\"} |~ \"WRN|ERR\"","refId":"A"}],"title":"Test Runner Errors and Warnings","transparent":true,"type":"logs"},{"description":"Info logs","gridPos":{"h":5,"w":8,"x":8,"y":21},"id":140,"options":{"dedupStrategy":"none","enableLogDetails":true,"prettifyLogMessage":false,"showCommonLabels":false,"showLabels":false,"showTime":false,"sortOrder":"Descending","wrapLogMessage":false},"pluginVersion":"8.5.0","targets":[{"datasource":{"type":"loki","uid":"grafanacloud-logs"},"expr":"{namespace=\"$namespace\", container=\"remote-test-runner\"} |= \"INF\"","refId":"A"}],"title":"Test Runner Info","transparent":true,"type":"logs"},{"description":"Debugs","gridPos":{"h":5,"w":8,"x":16,"y":21},"id":141,"options":{"dedupStrategy":"none","enableLogDetails":true,"prettifyLogMessage":false,"showCommonLabels":false,"showLabels":false,"showTime":false,"sortOrder":"Descending","wrapLogMessage":false},"pluginVersion":"8.5.0","targets":[{"datasource":{"type":"loki","uid":"grafanacloud-logs"},"expr":"{namespace=\"$namespace\", container=\"remote-test-runner\"} |~ \"DBG\"","refId":"A"}],"title":"Test Runner Debugs","transparent":true,"type":"logs"}],"title":"Test runner","type":"row"}],"refresh":"5s","schemaVersion":34,"style":"dark","tags":["tests"],"templating":{"list":[{"current":{"selected":false,"text":"chainlink-test-env-3735f","value":"chainlink-test-env-3735f"},"definition":"label_values(namespace)","description":"Namespace","hide":0,"includeAll":false,"label":"Namespace","multi":false,"name":"namespace","options":[],"query":"label_values(namespace)","refresh":1,"regex":"chainlink-.*|.*-soak-.*|.*performance-.*|.*-chaos-.*","skipUrlSync":false,"sort":0,"type":"query"},{"current":{"selected":true,"text":["chainlink-0-98744888d-r9n6r"],"value":["chainlink-0-98744888d-r9n6r"]},"definition":"label_values({namespace=\"$namespace\"}, pod)","description":"The specific Chainlink node to get insight into","hide":0,"includeAll":false,"label":"Chainlink Node","multi":true,"name":"cl_node","options":[],"query":"label_values({namespace=\"$namespace\"}, pod)","refresh":1,"regex":"chainlink-.*","skipUrlSync":false,"sort":0,"type":"query"},{"current":{"selected":false,"text":"geth-6469b5b5f8-smd2z","value":"geth-6469b5b5f8-smd2z"},"definition":"label_values({namespace=\"$namespace\"}, pod)","description":"If launched, a simulated instance of Geth","hide":0,"includeAll":false,"label":"Simulated Geth Node","multi":false,"name":"geth_node","options":[],"query":"label_values({namespace=\"$namespace\"}, pod)","refresh":1,"regex":"geth-|starknet.*","skipUrlSync":false,"sort":0,"type":"query"}]},"time":{"from":"now-30m","to":"now"},"timepicker":{},"timezone":"","title":"Chainlink Testing Insights","uid":"AFATC9A7k","version":1,"weekStart":""} diff --git a/lib/k8s/imports/k8s/httpchaos/chaosmeshorg/chaosmeshorg.go b/lib/k8s/imports/k8s/httpchaos/chaosmeshorg/chaosmeshorg.go deleted file mode 100644 index ebd5ea871..000000000 --- a/lib/k8s/imports/k8s/httpchaos/chaosmeshorg/chaosmeshorg.go +++ /dev/null @@ -1,454 +0,0 @@ -// chaos-meshorg -package chaosmeshorg - -import ( - _jsii_ "github.com/aws/jsii-runtime-go/runtime" - - _init_ "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/imports/k8s/httpchaos/chaosmeshorg/jsii" - - "github.com/aws/constructs-go/constructs/v10" - "github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2" - - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/imports/k8s/httpchaos/chaosmeshorg/internal" -) - -// HTTPChaos is the Schema for the HTTPchaos API. -type HttpChaos interface { - cdk8s.ApiObject - // The group portion of the API version (e.g. `authorization.k8s.io`). - ApiGroup() *string - // The object's API version (e.g. `authorization.k8s.io/v1`). - ApiVersion() *string - // The chart in which this object is defined. - Chart() cdk8s.Chart - // The object kind. - Kind() *string - // Metadata associated with this API object. - Metadata() cdk8s.ApiObjectMetadataDefinition - // The name of the API object. - // - // If a name is specified in `metadata.name` this will be the name returned. - // Otherwise, a name will be generated by calling - // `Chart.of(this).generatedObjectName(this)`, which by default uses the - // construct path to generate a DNS-compatible name for the resource. - Name() *string - // The tree node. - Node() constructs.Node - // Create a dependency between this ApiObject and other constructs. - // - // These can be other ApiObjects, Charts, or custom. - AddDependency(dependencies ...constructs.IConstruct) - // Applies a set of RFC-6902 JSON-Patch operations to the manifest synthesized for this API object. - // - // Example: - // kubePod.addJsonPatch(JsonPatch.replace('/spec/enableServiceLinks', true)); - // - AddJsonPatch(ops ...cdk8s.JsonPatch) - // Renders the object to Kubernetes JSON. - ToJson() interface{} - // Returns a string representation of this construct. - ToString() *string -} - -// The jsii proxy struct for HttpChaos -type jsiiProxy_HttpChaos struct { - internal.Type__cdk8sApiObject -} - -func (j *jsiiProxy_HttpChaos) ApiGroup() *string { - var returns *string - _jsii_.Get( - j, - "apiGroup", - &returns, - ) - return returns -} - -func (j *jsiiProxy_HttpChaos) ApiVersion() *string { - var returns *string - _jsii_.Get( - j, - "apiVersion", - &returns, - ) - return returns -} - -func (j *jsiiProxy_HttpChaos) Chart() cdk8s.Chart { - var returns cdk8s.Chart - _jsii_.Get( - j, - "chart", - &returns, - ) - return returns -} - -func (j *jsiiProxy_HttpChaos) Kind() *string { - var returns *string - _jsii_.Get( - j, - "kind", - &returns, - ) - return returns -} - -func (j *jsiiProxy_HttpChaos) Metadata() cdk8s.ApiObjectMetadataDefinition { - var returns cdk8s.ApiObjectMetadataDefinition - _jsii_.Get( - j, - "metadata", - &returns, - ) - return returns -} - -func (j *jsiiProxy_HttpChaos) Name() *string { - var returns *string - _jsii_.Get( - j, - "name", - &returns, - ) - return returns -} - -func (j *jsiiProxy_HttpChaos) Node() constructs.Node { - var returns constructs.Node - _jsii_.Get( - j, - "node", - &returns, - ) - return returns -} - -// Defines a "HTTPChaos" API object. -func NewHttpChaos(scope constructs.Construct, id *string, props *HttpChaosProps) HttpChaos { - _init_.Initialize() - - j := jsiiProxy_HttpChaos{} - - _jsii_.Create( - "chaos-meshorg.HttpChaos", - []interface{}{scope, id, props}, - &j, - ) - - return &j -} - -// Defines a "HTTPChaos" API object. -func NewHttpChaos_Override(h HttpChaos, scope constructs.Construct, id *string, props *HttpChaosProps) { - _init_.Initialize() - - _jsii_.Create( - "chaos-meshorg.HttpChaos", - []interface{}{scope, id, props}, - h, - ) -} - -// Checks if `x` is a construct. -// -// Use this method instead of `instanceof` to properly detect `Construct` -// instances, even when the construct library is symlinked. -// -// Explanation: in JavaScript, multiple copies of the `constructs` library on -// disk are seen as independent, completely different libraries. As a -// consequence, the class `Construct` in each copy of the `constructs` library -// is seen as a different class, and an instance of one class will not test as -// `instanceof` the other class. `npm install` will not create installations -// like this, but users may manually symlink construct libraries together or -// use a monorepo tool: in those cases, multiple copies of the `constructs` -// library can be accidentally installed, and `instanceof` will behave -// unpredictably. It is safest to avoid using `instanceof`, and using -// this type-testing method instead. -// -// Returns: true if `x` is an object created from a class which extends `Construct`. -func HttpChaos_IsConstruct(x interface{}) *bool { - _init_.Initialize() - - var returns *bool - - _jsii_.StaticInvoke( - "chaos-meshorg.HttpChaos", - "isConstruct", - []interface{}{x}, - &returns, - ) - - return returns -} - -// Renders a Kubernetes manifest for "HTTPChaos". -// -// This can be used to inline resource manifests inside other objects (e.g. as templates). -func HttpChaos_Manifest(props *HttpChaosProps) interface{} { - _init_.Initialize() - - var returns interface{} - - _jsii_.StaticInvoke( - "chaos-meshorg.HttpChaos", - "manifest", - []interface{}{props}, - &returns, - ) - - return returns -} - -// Returns the `ApiObject` named `Resource` which is a child of the given construct. -// -// If `c` is an `ApiObject`, it is returned directly. Throws an -// exception if the construct does not have a child named `Default` _or_ if -// this child is not an `ApiObject`. -func HttpChaos_Of(c constructs.IConstruct) cdk8s.ApiObject { - _init_.Initialize() - - var returns cdk8s.ApiObject - - _jsii_.StaticInvoke( - "chaos-meshorg.HttpChaos", - "of", - []interface{}{c}, - &returns, - ) - - return returns -} - -func HttpChaos_GVK() *cdk8s.GroupVersionKind { - _init_.Initialize() - var returns *cdk8s.GroupVersionKind - _jsii_.StaticGet( - "chaos-meshorg.HttpChaos", - "GVK", - &returns, - ) - return returns -} - -func (h *jsiiProxy_HttpChaos) AddDependency(dependencies ...constructs.IConstruct) { - args := []interface{}{} - for _, a := range dependencies { - args = append(args, a) - } - - _jsii_.InvokeVoid( - h, - "addDependency", - args, - ) -} - -func (h *jsiiProxy_HttpChaos) AddJsonPatch(ops ...cdk8s.JsonPatch) { - args := []interface{}{} - for _, a := range ops { - args = append(args, a) - } - - _jsii_.InvokeVoid( - h, - "addJsonPatch", - args, - ) -} - -func (h *jsiiProxy_HttpChaos) ToJson() interface{} { - var returns interface{} - - _jsii_.Invoke( - h, - "toJson", - nil, // no parameters - &returns, - ) - - return returns -} - -func (h *jsiiProxy_HttpChaos) ToString() *string { - var returns *string - - _jsii_.Invoke( - h, - "toString", - nil, // no parameters - &returns, - ) - - return returns -} - -// HTTPChaos is the Schema for the HTTPchaos API. -type HttpChaosProps struct { - Metadata *cdk8s.ApiObjectMetadata `field:"optional" json:"metadata" yaml:"metadata"` - Spec *HttpChaosSpec `field:"optional" json:"spec" yaml:"spec"` -} - -type HttpChaosSpec struct { - // Mode defines the mode to run chaos action. - // - // Supported mode: one / all / fixed / fixed-percent / random-max-percent. - Mode HttpChaosSpecMode `field:"required" json:"mode" yaml:"mode"` - // Selector is used to select pods that are used to inject chaos action. - Selector *HttpChaosSpecSelector `field:"required" json:"selector" yaml:"selector"` - // Target is the object to be selected and injected. - Target HttpChaosSpecTarget `field:"required" json:"target" yaml:"target"` - // Abort is a rule to abort a http session. - Abort *bool `field:"optional" json:"abort" yaml:"abort"` - // Code is a rule to select target by http status code in response. - Code *float64 `field:"optional" json:"code" yaml:"code"` - // Delay represents the delay of the target request/response. - // - // A duration string is a possibly unsigned sequence of decimal numbers, each with optional fraction and a unit suffix, such as "300ms", "2h45m". Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". - Delay *string `field:"optional" json:"delay" yaml:"delay"` - // Duration represents the duration of the chaos action. - Duration *string `field:"optional" json:"duration" yaml:"duration"` - // Method is a rule to select target by http method in request. - Method *string `field:"optional" json:"method" yaml:"method"` - // Patch is a rule to patch some contents in target. - Patch *HttpChaosSpecPatch `field:"optional" json:"patch" yaml:"patch"` - // Path is a rule to select target by uri path in http request. - Path *string `field:"optional" json:"path" yaml:"path"` - // Port represents the target port to be proxy of. - Port *float64 `field:"optional" json:"port" yaml:"port"` - // Replace is a rule to replace some contents in target. - Replace *HttpChaosSpecReplace `field:"optional" json:"replace" yaml:"replace"` - // RequestHeaders is a rule to select target by http headers in request. - // - // The key-value pairs represent header name and header value pairs. - RequestHeaders *map[string]*string `field:"optional" json:"requestHeaders" yaml:"requestHeaders"` - // ResponseHeaders is a rule to select target by http headers in response. - // - // The key-value pairs represent header name and header value pairs. - ResponseHeaders *map[string]*string `field:"optional" json:"responseHeaders" yaml:"responseHeaders"` - // Value is required when the mode is set to `FixedPodMode` / `FixedPercentPodMod` / `RandomMaxPercentPodMod`. - // - // If `FixedPodMode`, provide an integer of pods to do chaos action. If `FixedPercentPodMod`, provide a number from 0-100 to specify the percent of pods the server can do chaos action. IF `RandomMaxPercentPodMod`, provide a number from 0-100 to specify the max percent of pods to do chaos action - Value *string `field:"optional" json:"value" yaml:"value"` -} - -// Mode defines the mode to run chaos action. -// -// Supported mode: one / all / fixed / fixed-percent / random-max-percent. -type HttpChaosSpecMode string - -const ( - // one. - HttpChaosSpecMode_ONE HttpChaosSpecMode = "ONE" - // all. - HttpChaosSpecMode_ALL HttpChaosSpecMode = "ALL" - // fixed. - HttpChaosSpecMode_FIXED HttpChaosSpecMode = "FIXED" - // fixed-percent. - HttpChaosSpecMode_FIXED_PERCENT HttpChaosSpecMode = "FIXED_PERCENT" - // random-max-percent. - HttpChaosSpecMode_RANDOM_MAX_PERCENT HttpChaosSpecMode = "RANDOM_MAX_PERCENT" -) - -// Patch is a rule to patch some contents in target. -type HttpChaosSpecPatch struct { - // Body is a rule to patch message body of target. - Body *HttpChaosSpecPatchBody `field:"optional" json:"body" yaml:"body"` - // Headers is a rule to append http headers of target. - // - // For example: `[["Set-Cookie", ""], ["Set-Cookie", ""]]`. - Headers *[]*[]*string `field:"optional" json:"headers" yaml:"headers"` - // Queries is a rule to append uri queries of target(Request only). - // - // For example: `[["foo", "bar"], ["foo", "unknown"]]`. - Queries *[]*[]*string `field:"optional" json:"queries" yaml:"queries"` -} - -// Body is a rule to patch message body of target. -type HttpChaosSpecPatchBody struct { - // Type represents the patch type, only support `JSON` as [merge patch json](https://tools.ietf.org/html/rfc7396) currently. - Type *string `field:"required" json:"type" yaml:"type"` - // Value is the patch contents. - Value *string `field:"required" json:"value" yaml:"value"` -} - -// Replace is a rule to replace some contents in target. -type HttpChaosSpecReplace struct { - // Body is a rule to replace http message body in target. - Body *string `field:"optional" json:"body" yaml:"body"` - // Code is a rule to replace http status code in response. - Code *float64 `field:"optional" json:"code" yaml:"code"` - // Headers is a rule to replace http headers of target. - // - // The key-value pairs represent header name and header value pairs. - Headers *map[string]*string `field:"optional" json:"headers" yaml:"headers"` - // Method is a rule to replace http method in request. - Method *string `field:"optional" json:"method" yaml:"method"` - // Path is rule to to replace uri path in http request. - Path *string `field:"optional" json:"path" yaml:"path"` - // Queries is a rule to replace uri queries in http request. - // - // For example, with value `{ "foo": "unknown" }`, the `/?foo=bar` will be altered to `/?foo=unknown`, - Queries *map[string]*string `field:"optional" json:"queries" yaml:"queries"` -} - -// Selector is used to select pods that are used to inject chaos action. -type HttpChaosSpecSelector struct { - // Map of string keys and values that can be used to select objects. - // - // A selector based on annotations. - AnnotationSelectors *map[string]*string `field:"optional" json:"annotationSelectors" yaml:"annotationSelectors"` - // a slice of label selector expressions that can be used to select objects. - // - // A list of selectors based on set-based label expressions. - ExpressionSelectors *[]*HttpChaosSpecSelectorExpressionSelectors `field:"optional" json:"expressionSelectors" yaml:"expressionSelectors"` - // Map of string keys and values that can be used to select objects. - // - // A selector based on fields. - FieldSelectors *map[string]*string `field:"optional" json:"fieldSelectors" yaml:"fieldSelectors"` - // Map of string keys and values that can be used to select objects. - // - // A selector based on labels. - LabelSelectors *map[string]*string `field:"optional" json:"labelSelectors" yaml:"labelSelectors"` - // Namespaces is a set of namespace to which objects belong. - Namespaces *[]*string `field:"optional" json:"namespaces" yaml:"namespaces"` - // Nodes is a set of node name and objects must belong to these nodes. - Nodes *[]*string `field:"optional" json:"nodes" yaml:"nodes"` - // Map of string keys and values that can be used to select nodes. - // - // Selector which must match a node's labels, and objects must belong to these selected nodes. - NodeSelectors *map[string]*string `field:"optional" json:"nodeSelectors" yaml:"nodeSelectors"` - // PodPhaseSelectors is a set of condition of a pod at the current time. - // - // supported value: Pending / Running / Succeeded / Failed / Unknown. - PodPhaseSelectors *[]*string `field:"optional" json:"podPhaseSelectors" yaml:"podPhaseSelectors"` - // Pods is a map of string keys and a set values that used to select pods. - // - // The key defines the namespace which pods belong, and the each values is a set of pod names. - Pods *map[string]*[]*string `field:"optional" json:"pods" yaml:"pods"` -} - -// A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. -type HttpChaosSpecSelectorExpressionSelectors struct { - // key is the label key that the selector applies to. - Key *string `field:"required" json:"key" yaml:"key"` - // operator represents a key's relationship to a set of values. - // - // Valid operators are In, NotIn, Exists and DoesNotExist. - Operator *string `field:"required" json:"operator" yaml:"operator"` - // values is an array of string values. - // - // If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. - Values *[]*string `field:"optional" json:"values" yaml:"values"` -} - -// Target is the object to be selected and injected. -type HttpChaosSpecTarget string - -const ( - // Request. - HttpChaosSpecTarget_REQUEST HttpChaosSpecTarget = "REQUEST" - // Response. - HttpChaosSpecTarget_RESPONSE HttpChaosSpecTarget = "RESPONSE" -) diff --git a/lib/k8s/imports/k8s/httpchaos/chaosmeshorg/chaosmeshorg.init.go b/lib/k8s/imports/k8s/httpchaos/chaosmeshorg/chaosmeshorg.init.go deleted file mode 100644 index 071a286cd..000000000 --- a/lib/k8s/imports/k8s/httpchaos/chaosmeshorg/chaosmeshorg.init.go +++ /dev/null @@ -1,79 +0,0 @@ -package chaosmeshorg - -import ( - "reflect" - - _jsii_ "github.com/aws/jsii-runtime-go/runtime" -) - -func init() { - _jsii_.RegisterClass( - "chaos-meshorg.HttpChaos", - reflect.TypeOf((*HttpChaos)(nil)).Elem(), - []_jsii_.Member{ - _jsii_.MemberMethod{JsiiMethod: "addDependency", GoMethod: "AddDependency"}, - _jsii_.MemberMethod{JsiiMethod: "addJsonPatch", GoMethod: "AddJsonPatch"}, - _jsii_.MemberProperty{JsiiProperty: "apiGroup", GoGetter: "ApiGroup"}, - _jsii_.MemberProperty{JsiiProperty: "apiVersion", GoGetter: "ApiVersion"}, - _jsii_.MemberProperty{JsiiProperty: "chart", GoGetter: "Chart"}, - _jsii_.MemberProperty{JsiiProperty: "kind", GoGetter: "Kind"}, - _jsii_.MemberProperty{JsiiProperty: "metadata", GoGetter: "Metadata"}, - _jsii_.MemberProperty{JsiiProperty: "name", GoGetter: "Name"}, - _jsii_.MemberProperty{JsiiProperty: "node", GoGetter: "Node"}, - _jsii_.MemberMethod{JsiiMethod: "toJson", GoMethod: "ToJson"}, - _jsii_.MemberMethod{JsiiMethod: "toString", GoMethod: "ToString"}, - }, - func() interface{} { - j := jsiiProxy_HttpChaos{} - _jsii_.InitJsiiProxy(&j.Type__cdk8sApiObject) - return &j - }, - ) - _jsii_.RegisterStruct( - "chaos-meshorg.HttpChaosProps", - reflect.TypeOf((*HttpChaosProps)(nil)).Elem(), - ) - _jsii_.RegisterStruct( - "chaos-meshorg.HttpChaosSpec", - reflect.TypeOf((*HttpChaosSpec)(nil)).Elem(), - ) - _jsii_.RegisterEnum( - "chaos-meshorg.HttpChaosSpecMode", - reflect.TypeOf((*HttpChaosSpecMode)(nil)).Elem(), - map[string]interface{}{ - "ONE": HttpChaosSpecMode_ONE, - "ALL": HttpChaosSpecMode_ALL, - "FIXED": HttpChaosSpecMode_FIXED, - "FIXED_PERCENT": HttpChaosSpecMode_FIXED_PERCENT, - "RANDOM_MAX_PERCENT": HttpChaosSpecMode_RANDOM_MAX_PERCENT, - }, - ) - _jsii_.RegisterStruct( - "chaos-meshorg.HttpChaosSpecPatch", - reflect.TypeOf((*HttpChaosSpecPatch)(nil)).Elem(), - ) - _jsii_.RegisterStruct( - "chaos-meshorg.HttpChaosSpecPatchBody", - reflect.TypeOf((*HttpChaosSpecPatchBody)(nil)).Elem(), - ) - _jsii_.RegisterStruct( - "chaos-meshorg.HttpChaosSpecReplace", - reflect.TypeOf((*HttpChaosSpecReplace)(nil)).Elem(), - ) - _jsii_.RegisterStruct( - "chaos-meshorg.HttpChaosSpecSelector", - reflect.TypeOf((*HttpChaosSpecSelector)(nil)).Elem(), - ) - _jsii_.RegisterStruct( - "chaos-meshorg.HttpChaosSpecSelectorExpressionSelectors", - reflect.TypeOf((*HttpChaosSpecSelectorExpressionSelectors)(nil)).Elem(), - ) - _jsii_.RegisterEnum( - "chaos-meshorg.HttpChaosSpecTarget", - reflect.TypeOf((*HttpChaosSpecTarget)(nil)).Elem(), - map[string]interface{}{ - "REQUEST": HttpChaosSpecTarget_REQUEST, - "RESPONSE": HttpChaosSpecTarget_RESPONSE, - }, - ) -} diff --git a/lib/k8s/imports/k8s/httpchaos/chaosmeshorg/internal/types.go b/lib/k8s/imports/k8s/httpchaos/chaosmeshorg/internal/types.go deleted file mode 100644 index 4b6b993a2..000000000 --- a/lib/k8s/imports/k8s/httpchaos/chaosmeshorg/internal/types.go +++ /dev/null @@ -1,7 +0,0 @@ -package internal - -import ( - "github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2" -) - -type Type__cdk8sApiObject = cdk8s.ApiObject diff --git a/lib/k8s/imports/k8s/httpchaos/chaosmeshorg/jsii/chaos-meshorg-0.0.0.tgz b/lib/k8s/imports/k8s/httpchaos/chaosmeshorg/jsii/chaos-meshorg-0.0.0.tgz deleted file mode 100644 index 67623dd12a72e5d36a56d24554fb70f7ab04d2e2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24609 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 ccQ60@8+|oQztJBw+W-&(02~p%Jpcdz diff --git a/lib/k8s/imports/k8s/httpchaos/chaosmeshorg/jsii/jsii.go b/lib/k8s/imports/k8s/httpchaos/chaosmeshorg/jsii/jsii.go deleted file mode 100644 index 2d7a50bea..000000000 --- a/lib/k8s/imports/k8s/httpchaos/chaosmeshorg/jsii/jsii.go +++ /dev/null @@ -1,28 +0,0 @@ -// Package jsii contains the functionality needed for jsii packages to -// initialize their dependencies and themselves. Users should never need to use this package -// directly. If you find you need to - please report a bug at -// https://github.com/aws/jsii/issues/new/choose -package jsii - -import ( - _ "embed" - - _jsii_ "github.com/aws/jsii-runtime-go/runtime" - - constructs "github.com/aws/constructs-go/constructs/v10/jsii" - cdk8s "github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2/jsii" -) - -//go:embed chaos-meshorg-0.0.0.tgz -var tarball []byte - -// Initialize loads the necessary packages in the @jsii/kernel to support the enclosing module. -// The implementation is idempotent (and hence safe to be called over and over). -func Initialize() { - // Ensure all dependencies are initialized - cdk8s.Initialize() - constructs.Initialize() - - // Load this library into the kernel - _jsii_.Load("chaos-meshorg", "0.0.0", tarball) -} diff --git a/lib/k8s/imports/k8s/httpchaos/chaosmeshorg/version b/lib/k8s/imports/k8s/httpchaos/chaosmeshorg/version deleted file mode 100644 index 77d6f4ca2..000000000 --- a/lib/k8s/imports/k8s/httpchaos/chaosmeshorg/version +++ /dev/null @@ -1 +0,0 @@ -0.0.0 diff --git a/lib/k8s/imports/k8s/internal/types.go b/lib/k8s/imports/k8s/internal/types.go deleted file mode 100644 index 4b6b993a2..000000000 --- a/lib/k8s/imports/k8s/internal/types.go +++ /dev/null @@ -1,7 +0,0 @@ -package internal - -import ( - "github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2" -) - -type Type__cdk8sApiObject = cdk8s.ApiObject diff --git a/lib/k8s/imports/k8s/iochaos/chaosmeshorg/chaosmeshorg.go b/lib/k8s/imports/k8s/iochaos/chaosmeshorg/chaosmeshorg.go deleted file mode 100644 index 79f018307..000000000 --- a/lib/k8s/imports/k8s/iochaos/chaosmeshorg/chaosmeshorg.go +++ /dev/null @@ -1,484 +0,0 @@ -// chaos-meshorg -package chaosmeshorg - -import ( - _jsii_ "github.com/aws/jsii-runtime-go/runtime" - - _init_ "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/imports/k8s/iochaos/chaosmeshorg/jsii" - - "github.com/aws/constructs-go/constructs/v10" - "github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2" - - "github.com/smartcontractkit/chainlink-testing-framework/lib/k8s/imports/k8s/iochaos/chaosmeshorg/internal" -) - -// IOChaos is the Schema for the iochaos API. -type IoChaos interface { - cdk8s.ApiObject - // The group portion of the API version (e.g. `authorization.k8s.io`). - ApiGroup() *string - // The object's API version (e.g. `authorization.k8s.io/v1`). - ApiVersion() *string - // The chart in which this object is defined. - Chart() cdk8s.Chart - // The object kind. - Kind() *string - // Metadata associated with this API object. - Metadata() cdk8s.ApiObjectMetadataDefinition - // The name of the API object. - // - // If a name is specified in `metadata.name` this will be the name returned. - // Otherwise, a name will be generated by calling - // `Chart.of(this).generatedObjectName(this)`, which by default uses the - // construct path to generate a DNS-compatible name for the resource. - Name() *string - // The tree node. - Node() constructs.Node - // Create a dependency between this ApiObject and other constructs. - // - // These can be other ApiObjects, Charts, or custom. - AddDependency(dependencies ...constructs.IConstruct) - // Applies a set of RFC-6902 JSON-Patch operations to the manifest synthesized for this API object. - // - // Example: - // kubePod.addJsonPatch(JsonPatch.replace('/spec/enableServiceLinks', true)); - // - AddJsonPatch(ops ...cdk8s.JsonPatch) - // Renders the object to Kubernetes JSON. - ToJson() interface{} - // Returns a string representation of this construct. - ToString() *string -} - -// The jsii proxy struct for IoChaos -type jsiiProxy_IoChaos struct { - internal.Type__cdk8sApiObject -} - -func (j *jsiiProxy_IoChaos) ApiGroup() *string { - var returns *string - _jsii_.Get( - j, - "apiGroup", - &returns, - ) - return returns -} - -func (j *jsiiProxy_IoChaos) ApiVersion() *string { - var returns *string - _jsii_.Get( - j, - "apiVersion", - &returns, - ) - return returns -} - -func (j *jsiiProxy_IoChaos) Chart() cdk8s.Chart { - var returns cdk8s.Chart - _jsii_.Get( - j, - "chart", - &returns, - ) - return returns -} - -func (j *jsiiProxy_IoChaos) Kind() *string { - var returns *string - _jsii_.Get( - j, - "kind", - &returns, - ) - return returns -} - -func (j *jsiiProxy_IoChaos) Metadata() cdk8s.ApiObjectMetadataDefinition { - var returns cdk8s.ApiObjectMetadataDefinition - _jsii_.Get( - j, - "metadata", - &returns, - ) - return returns -} - -func (j *jsiiProxy_IoChaos) Name() *string { - var returns *string - _jsii_.Get( - j, - "name", - &returns, - ) - return returns -} - -func (j *jsiiProxy_IoChaos) Node() constructs.Node { - var returns constructs.Node - _jsii_.Get( - j, - "node", - &returns, - ) - return returns -} - -// Defines a "IOChaos" API object. -func NewIoChaos(scope constructs.Construct, id *string, props *IoChaosProps) IoChaos { - _init_.Initialize() - - j := jsiiProxy_IoChaos{} - - _jsii_.Create( - "chaos-meshorg.IoChaos", - []interface{}{scope, id, props}, - &j, - ) - - return &j -} - -// Defines a "IOChaos" API object. -func NewIoChaos_Override(i IoChaos, scope constructs.Construct, id *string, props *IoChaosProps) { - _init_.Initialize() - - _jsii_.Create( - "chaos-meshorg.IoChaos", - []interface{}{scope, id, props}, - i, - ) -} - -// Checks if `x` is a construct. -// -// Use this method instead of `instanceof` to properly detect `Construct` -// instances, even when the construct library is symlinked. -// -// Explanation: in JavaScript, multiple copies of the `constructs` library on -// disk are seen as independent, completely different libraries. As a -// consequence, the class `Construct` in each copy of the `constructs` library -// is seen as a different class, and an instance of one class will not test as -// `instanceof` the other class. `npm install` will not create installations -// like this, but users may manually symlink construct libraries together or -// use a monorepo tool: in those cases, multiple copies of the `constructs` -// library can be accidentally installed, and `instanceof` will behave -// unpredictably. It is safest to avoid using `instanceof`, and using -// this type-testing method instead. -// -// Returns: true if `x` is an object created from a class which extends `Construct`. -func IoChaos_IsConstruct(x interface{}) *bool { - _init_.Initialize() - - var returns *bool - - _jsii_.StaticInvoke( - "chaos-meshorg.IoChaos", - "isConstruct", - []interface{}{x}, - &returns, - ) - - return returns -} - -// Renders a Kubernetes manifest for "IOChaos". -// -// This can be used to inline resource manifests inside other objects (e.g. as templates). -func IoChaos_Manifest(props *IoChaosProps) interface{} { - _init_.Initialize() - - var returns interface{} - - _jsii_.StaticInvoke( - "chaos-meshorg.IoChaos", - "manifest", - []interface{}{props}, - &returns, - ) - - return returns -} - -// Returns the `ApiObject` named `Resource` which is a child of the given construct. -// -// If `c` is an `ApiObject`, it is returned directly. Throws an -// exception if the construct does not have a child named `Default` _or_ if -// this child is not an `ApiObject`. -func IoChaos_Of(c constructs.IConstruct) cdk8s.ApiObject { - _init_.Initialize() - - var returns cdk8s.ApiObject - - _jsii_.StaticInvoke( - "chaos-meshorg.IoChaos", - "of", - []interface{}{c}, - &returns, - ) - - return returns -} - -func IoChaos_GVK() *cdk8s.GroupVersionKind { - _init_.Initialize() - var returns *cdk8s.GroupVersionKind - _jsii_.StaticGet( - "chaos-meshorg.IoChaos", - "GVK", - &returns, - ) - return returns -} - -func (i *jsiiProxy_IoChaos) AddDependency(dependencies ...constructs.IConstruct) { - args := []interface{}{} - for _, a := range dependencies { - args = append(args, a) - } - - _jsii_.InvokeVoid( - i, - "addDependency", - args, - ) -} - -func (i *jsiiProxy_IoChaos) AddJsonPatch(ops ...cdk8s.JsonPatch) { - args := []interface{}{} - for _, a := range ops { - args = append(args, a) - } - - _jsii_.InvokeVoid( - i, - "addJsonPatch", - args, - ) -} - -func (i *jsiiProxy_IoChaos) ToJson() interface{} { - var returns interface{} - - _jsii_.Invoke( - i, - "toJson", - nil, // no parameters - &returns, - ) - - return returns -} - -func (i *jsiiProxy_IoChaos) ToString() *string { - var returns *string - - _jsii_.Invoke( - i, - "toString", - nil, // no parameters - &returns, - ) - - return returns -} - -// IOChaos is the Schema for the iochaos API. -type IoChaosProps struct { - Metadata *cdk8s.ApiObjectMetadata `field:"optional" json:"metadata" yaml:"metadata"` - // IOChaosSpec defines the desired state of IOChaos. - Spec *IoChaosSpec `field:"optional" json:"spec" yaml:"spec"` -} - -// IOChaosSpec defines the desired state of IOChaos. -type IoChaosSpec struct { - // Action defines the specific pod chaos action. - // - // Supported action: latency / fault / attrOverride / mistake. - Action IoChaosSpecAction `field:"required" json:"action" yaml:"action"` - // Mode defines the mode to run chaos action. - // - // Supported mode: one / all / fixed / fixed-percent / random-max-percent. - Mode IoChaosSpecMode `field:"required" json:"mode" yaml:"mode"` - // Selector is used to select pods that are used to inject chaos action. - Selector *IoChaosSpecSelector `field:"required" json:"selector" yaml:"selector"` - // VolumePath represents the mount path of injected volume. - VolumePath *string `field:"required" json:"volumePath" yaml:"volumePath"` - // Attr defines the overridden attribution. - Attr *IoChaosSpecAttr `field:"optional" json:"attr" yaml:"attr"` - // ContainerNames indicates list of the name of affected container. - // - // If not set, all containers will be injected. - ContainerNames *[]*string `field:"optional" json:"containerNames" yaml:"containerNames"` - // Delay defines the value of I/O chaos action delay. - // - // A delay string is a possibly signed sequence of decimal numbers, each with optional fraction and a unit suffix, such as "300ms". Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". - Delay *string `field:"optional" json:"delay" yaml:"delay"` - // Duration represents the duration of the chaos action. - // - // It is required when the action is `PodFailureAction`. A duration string is a possibly signed sequence of decimal numbers, each with optional fraction and a unit suffix, such as "300ms", "-1.5h" or "2h45m". Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". - Duration *string `field:"optional" json:"duration" yaml:"duration"` - // Errno defines the error code that returned by I/O action. - // - // refer to: https://www-numi.fnal.gov/offline_software/srt_public_context/WebDocs/Errors/unix_system_errors.html - Errno *float64 `field:"optional" json:"errno" yaml:"errno"` - // Methods defines the I/O methods for injecting I/O chaos action. - // - // default: all I/O methods. - Methods *[]*string `field:"optional" json:"methods" yaml:"methods"` - // Mistake defines what types of incorrectness are injected to IO operations. - Mistake *IoChaosSpecMistake `field:"optional" json:"mistake" yaml:"mistake"` - // Path defines the path of files for injecting I/O chaos action. - Path *string `field:"optional" json:"path" yaml:"path"` - // Percent defines the percentage of injection errors and provides a number from 0-100. - // - // default: 100. - Percent *float64 `field:"optional" json:"percent" yaml:"percent"` - // Value is required when the mode is set to `FixedPodMode` / `FixedPercentPodMod` / `RandomMaxPercentPodMod`. - // - // If `FixedPodMode`, provide an integer of pods to do chaos action. If `FixedPercentPodMod`, provide a number from 0-100 to specify the percent of pods the server can do chaos action. IF `RandomMaxPercentPodMod`, provide a number from 0-100 to specify the max percent of pods to do chaos action - Value *string `field:"optional" json:"value" yaml:"value"` -} - -// Action defines the specific pod chaos action. -// -// Supported action: latency / fault / attrOverride / mistake. -type IoChaosSpecAction string - -const ( - // latency. - IoChaosSpecAction_LATENCY IoChaosSpecAction = "LATENCY" - // fault. - IoChaosSpecAction_FAULT IoChaosSpecAction = "FAULT" - // attrOverride. - IoChaosSpecAction_ATTR_OVERRIDE IoChaosSpecAction = "ATTR_OVERRIDE" - // mistake. - IoChaosSpecAction_MISTAKE IoChaosSpecAction = "MISTAKE" -) - -// Attr defines the overridden attribution. -type IoChaosSpecAttr struct { - // Timespec represents a time. - Atime *IoChaosSpecAttrAtime `field:"optional" json:"atime" yaml:"atime"` - Blocks *float64 `field:"optional" json:"blocks" yaml:"blocks"` - // Timespec represents a time. - Ctime *IoChaosSpecAttrCtime `field:"optional" json:"ctime" yaml:"ctime"` - Gid *float64 `field:"optional" json:"gid" yaml:"gid"` - Ino *float64 `field:"optional" json:"ino" yaml:"ino"` - // FileType represents type of a file. - Kind *string `field:"optional" json:"kind" yaml:"kind"` - // Timespec represents a time. - Mtime *IoChaosSpecAttrMtime `field:"optional" json:"mtime" yaml:"mtime"` - Nlink *float64 `field:"optional" json:"nlink" yaml:"nlink"` - Perm *float64 `field:"optional" json:"perm" yaml:"perm"` - Rdev *float64 `field:"optional" json:"rdev" yaml:"rdev"` - Size *float64 `field:"optional" json:"size" yaml:"size"` - Uid *float64 `field:"optional" json:"uid" yaml:"uid"` -} - -// Timespec represents a time. -type IoChaosSpecAttrAtime struct { - Nsec *float64 `field:"required" json:"nsec" yaml:"nsec"` - Sec *float64 `field:"required" json:"sec" yaml:"sec"` -} - -// Timespec represents a time. -type IoChaosSpecAttrCtime struct { - Nsec *float64 `field:"required" json:"nsec" yaml:"nsec"` - Sec *float64 `field:"required" json:"sec" yaml:"sec"` -} - -// Timespec represents a time. -type IoChaosSpecAttrMtime struct { - Nsec *float64 `field:"required" json:"nsec" yaml:"nsec"` - Sec *float64 `field:"required" json:"sec" yaml:"sec"` -} - -// Mistake defines what types of incorrectness are injected to IO operations. -type IoChaosSpecMistake struct { - // Filling determines what is filled in the miskate data. - Filling IoChaosSpecMistakeFilling `field:"optional" json:"filling" yaml:"filling"` - // Max length of each wrong data segment in bytes. - MaxLength *float64 `field:"optional" json:"maxLength" yaml:"maxLength"` - // There will be [1, MaxOccurrences] segments of wrong data. - MaxOccurrences *float64 `field:"optional" json:"maxOccurrences" yaml:"maxOccurrences"` -} - -// Filling determines what is filled in the miskate data. -type IoChaosSpecMistakeFilling string - -const ( - // zero. - IoChaosSpecMistakeFilling_ZERO IoChaosSpecMistakeFilling = "ZERO" - // random. - IoChaosSpecMistakeFilling_RANDOM IoChaosSpecMistakeFilling = "RANDOM" -) - -// Mode defines the mode to run chaos action. -// -// Supported mode: one / all / fixed / fixed-percent / random-max-percent. -type IoChaosSpecMode string - -const ( - // one. - IoChaosSpecMode_ONE IoChaosSpecMode = "ONE" - // all. - IoChaosSpecMode_ALL IoChaosSpecMode = "ALL" - // fixed. - IoChaosSpecMode_FIXED IoChaosSpecMode = "FIXED" - // fixed-percent. - IoChaosSpecMode_FIXED_PERCENT IoChaosSpecMode = "FIXED_PERCENT" - // random-max-percent. - IoChaosSpecMode_RANDOM_MAX_PERCENT IoChaosSpecMode = "RANDOM_MAX_PERCENT" -) - -// Selector is used to select pods that are used to inject chaos action. -type IoChaosSpecSelector struct { - // Map of string keys and values that can be used to select objects. - // - // A selector based on annotations. - AnnotationSelectors *map[string]*string `field:"optional" json:"annotationSelectors" yaml:"annotationSelectors"` - // a slice of label selector expressions that can be used to select objects. - // - // A list of selectors based on set-based label expressions. - ExpressionSelectors *[]*IoChaosSpecSelectorExpressionSelectors `field:"optional" json:"expressionSelectors" yaml:"expressionSelectors"` - // Map of string keys and values that can be used to select objects. - // - // A selector based on fields. - FieldSelectors *map[string]*string `field:"optional" json:"fieldSelectors" yaml:"fieldSelectors"` - // Map of string keys and values that can be used to select objects. - // - // A selector based on labels. - LabelSelectors *map[string]*string `field:"optional" json:"labelSelectors" yaml:"labelSelectors"` - // Namespaces is a set of namespace to which objects belong. - Namespaces *[]*string `field:"optional" json:"namespaces" yaml:"namespaces"` - // Nodes is a set of node name and objects must belong to these nodes. - Nodes *[]*string `field:"optional" json:"nodes" yaml:"nodes"` - // Map of string keys and values that can be used to select nodes. - // - // Selector which must match a node's labels, and objects must belong to these selected nodes. - NodeSelectors *map[string]*string `field:"optional" json:"nodeSelectors" yaml:"nodeSelectors"` - // PodPhaseSelectors is a set of condition of a pod at the current time. - // - // supported value: Pending / Running / Succeeded / Failed / Unknown. - PodPhaseSelectors *[]*string `field:"optional" json:"podPhaseSelectors" yaml:"podPhaseSelectors"` - // Pods is a map of string keys and a set values that used to select pods. - // - // The key defines the namespace which pods belong, and the each values is a set of pod names. - Pods *map[string]*[]*string `field:"optional" json:"pods" yaml:"pods"` -} - -// A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. -type IoChaosSpecSelectorExpressionSelectors struct { - // key is the label key that the selector applies to. - Key *string `field:"required" json:"key" yaml:"key"` - // operator represents a key's relationship to a set of values. - // - // Valid operators are In, NotIn, Exists and DoesNotExist. - Operator *string `field:"required" json:"operator" yaml:"operator"` - // values is an array of string values. - // - // If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. - Values *[]*string `field:"optional" json:"values" yaml:"values"` -} diff --git a/lib/k8s/imports/k8s/iochaos/chaosmeshorg/chaosmeshorg.init.go b/lib/k8s/imports/k8s/iochaos/chaosmeshorg/chaosmeshorg.init.go deleted file mode 100644 index 7e96596a2..000000000 --- a/lib/k8s/imports/k8s/iochaos/chaosmeshorg/chaosmeshorg.init.go +++ /dev/null @@ -1,97 +0,0 @@ -package chaosmeshorg - -import ( - "reflect" - - _jsii_ "github.com/aws/jsii-runtime-go/runtime" -) - -func init() { - _jsii_.RegisterClass( - "chaos-meshorg.IoChaos", - reflect.TypeOf((*IoChaos)(nil)).Elem(), - []_jsii_.Member{ - _jsii_.MemberMethod{JsiiMethod: "addDependency", GoMethod: "AddDependency"}, - _jsii_.MemberMethod{JsiiMethod: "addJsonPatch", GoMethod: "AddJsonPatch"}, - _jsii_.MemberProperty{JsiiProperty: "apiGroup", GoGetter: "ApiGroup"}, - _jsii_.MemberProperty{JsiiProperty: "apiVersion", GoGetter: "ApiVersion"}, - _jsii_.MemberProperty{JsiiProperty: "chart", GoGetter: "Chart"}, - _jsii_.MemberProperty{JsiiProperty: "kind", GoGetter: "Kind"}, - _jsii_.MemberProperty{JsiiProperty: "metadata", GoGetter: "Metadata"}, - _jsii_.MemberProperty{JsiiProperty: "name", GoGetter: "Name"}, - _jsii_.MemberProperty{JsiiProperty: "node", GoGetter: "Node"}, - _jsii_.MemberMethod{JsiiMethod: "toJson", GoMethod: "ToJson"}, - _jsii_.MemberMethod{JsiiMethod: "toString", GoMethod: "ToString"}, - }, - func() interface{} { - j := jsiiProxy_IoChaos{} - _jsii_.InitJsiiProxy(&j.Type__cdk8sApiObject) - return &j - }, - ) - _jsii_.RegisterStruct( - "chaos-meshorg.IoChaosProps", - reflect.TypeOf((*IoChaosProps)(nil)).Elem(), - ) - _jsii_.RegisterStruct( - "chaos-meshorg.IoChaosSpec", - reflect.TypeOf((*IoChaosSpec)(nil)).Elem(), - ) - _jsii_.RegisterEnum( - "chaos-meshorg.IoChaosSpecAction", - reflect.TypeOf((*IoChaosSpecAction)(nil)).Elem(), - map[string]interface{}{ - "LATENCY": IoChaosSpecAction_LATENCY, - "FAULT": IoChaosSpecAction_FAULT, - "ATTR_OVERRIDE": IoChaosSpecAction_ATTR_OVERRIDE, - "MISTAKE": IoChaosSpecAction_MISTAKE, - }, - ) - _jsii_.RegisterStruct( - "chaos-meshorg.IoChaosSpecAttr", - reflect.TypeOf((*IoChaosSpecAttr)(nil)).Elem(), - ) - _jsii_.RegisterStruct( - "chaos-meshorg.IoChaosSpecAttrAtime", - reflect.TypeOf((*IoChaosSpecAttrAtime)(nil)).Elem(), - ) - _jsii_.RegisterStruct( - "chaos-meshorg.IoChaosSpecAttrCtime", - reflect.TypeOf((*IoChaosSpecAttrCtime)(nil)).Elem(), - ) - _jsii_.RegisterStruct( - "chaos-meshorg.IoChaosSpecAttrMtime", - reflect.TypeOf((*IoChaosSpecAttrMtime)(nil)).Elem(), - ) - _jsii_.RegisterStruct( - "chaos-meshorg.IoChaosSpecMistake", - reflect.TypeOf((*IoChaosSpecMistake)(nil)).Elem(), - ) - _jsii_.RegisterEnum( - "chaos-meshorg.IoChaosSpecMistakeFilling", - reflect.TypeOf((*IoChaosSpecMistakeFilling)(nil)).Elem(), - map[string]interface{}{ - "ZERO": IoChaosSpecMistakeFilling_ZERO, - "RANDOM": IoChaosSpecMistakeFilling_RANDOM, - }, - ) - _jsii_.RegisterEnum( - "chaos-meshorg.IoChaosSpecMode", - reflect.TypeOf((*IoChaosSpecMode)(nil)).Elem(), - map[string]interface{}{ - "ONE": IoChaosSpecMode_ONE, - "ALL": IoChaosSpecMode_ALL, - "FIXED": IoChaosSpecMode_FIXED, - "FIXED_PERCENT": IoChaosSpecMode_FIXED_PERCENT, - "RANDOM_MAX_PERCENT": IoChaosSpecMode_RANDOM_MAX_PERCENT, - }, - ) - _jsii_.RegisterStruct( - "chaos-meshorg.IoChaosSpecSelector", - reflect.TypeOf((*IoChaosSpecSelector)(nil)).Elem(), - ) - _jsii_.RegisterStruct( - "chaos-meshorg.IoChaosSpecSelectorExpressionSelectors", - reflect.TypeOf((*IoChaosSpecSelectorExpressionSelectors)(nil)).Elem(), - ) -} diff --git a/lib/k8s/imports/k8s/iochaos/chaosmeshorg/internal/types.go b/lib/k8s/imports/k8s/iochaos/chaosmeshorg/internal/types.go deleted file mode 100644 index 4b6b993a2..000000000 --- a/lib/k8s/imports/k8s/iochaos/chaosmeshorg/internal/types.go +++ /dev/null @@ -1,7 +0,0 @@ -package internal - -import ( - "github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2" -) - -type Type__cdk8sApiObject = cdk8s.ApiObject diff --git a/lib/k8s/imports/k8s/iochaos/chaosmeshorg/jsii/chaos-meshorg-0.0.0.tgz b/lib/k8s/imports/k8s/iochaos/chaosmeshorg/jsii/chaos-meshorg-0.0.0.tgz deleted file mode 100644 index ba6340c62e9a7b4cb2d34f3e52e3cf235599e2de..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26345 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 diff --git a/lib/k8s/imports/k8s/iochaos/chaosmeshorg/jsii/jsii.go b/lib/k8s/imports/k8s/iochaos/chaosmeshorg/jsii/jsii.go deleted file mode 100644 index 2d7a50bea..000000000 --- a/lib/k8s/imports/k8s/iochaos/chaosmeshorg/jsii/jsii.go +++ /dev/null @@ -1,28 +0,0 @@ -// Package jsii contains the functionality needed for jsii packages to -// initialize their dependencies and themselves. Users should never need to use this package -// directly. If you find you need to - please report a bug at -// https://github.com/aws/jsii/issues/new/choose -package jsii - -import ( - _ "embed" - - _jsii_ "github.com/aws/jsii-runtime-go/runtime" - - constructs "github.com/aws/constructs-go/constructs/v10/jsii" - cdk8s "github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2/jsii" -) - -//go:embed chaos-meshorg-0.0.0.tgz -var tarball []byte - -// Initialize loads the necessary packages in the @jsii/kernel to support the enclosing module. -// The implementation is idempotent (and hence safe to be called over and over). -func Initialize() { - // Ensure all dependencies are initialized - cdk8s.Initialize() - constructs.Initialize() - - // Load this library into the kernel - _jsii_.Load("chaos-meshorg", "0.0.0", tarball) -} diff --git a/lib/k8s/imports/k8s/iochaos/chaosmeshorg/version b/lib/k8s/imports/k8s/iochaos/chaosmeshorg/version deleted file mode 100644 index 77d6f4ca2..000000000 --- a/lib/k8s/imports/k8s/iochaos/chaosmeshorg/version +++ /dev/null @@ -1 +0,0 @@ -0.0.0 diff --git a/lib/k8s/imports/k8s/jsii/jsii.go b/lib/k8s/imports/k8s/jsii/jsii.go deleted file mode 100644 index 79073d0e5..000000000 --- a/lib/k8s/imports/k8s/jsii/jsii.go +++ /dev/null @@ -1,28 +0,0 @@ -// Package jsii contains the functionality needed for jsii packages to -// initialize their dependencies and themselves. Users should never need to use this package -// directly. If you find you need to - please report a bug at -// https://github.com/aws/jsii/issues/new/choose -package jsii - -import ( - _ "embed" - - _jsii_ "github.com/aws/jsii-runtime-go/runtime" - - constructs "github.com/aws/constructs-go/constructs/v10/jsii" - cdk8s "github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2/jsii" -) - -//go:embed k8s-0.0.0.tgz -var tarball []byte - -// Initialize loads the necessary packages in the @jsii/kernel to support the enclosing module. -// The implementation is idempotent (and hence safe to be called over and over). -func Initialize() { - // Ensure all dependencies are initialized - cdk8s.Initialize() - constructs.Initialize() - - // Load this library into the kernel - _jsii_.Load("k8s", "0.0.0", tarball) -} diff --git a/lib/k8s/imports/k8s/jsii/k8s-0.0.0.tgz b/lib/k8s/imports/k8s/jsii/k8s-0.0.0.tgz deleted file mode 100644 index b5cb2605a2eda1a6ebe0ffacd6799ef659256edc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 631564 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

vfL=V~0;AC^<-Rbq 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

-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