From 49837dad8428fb94d28bf2890885d55b81ef69dd Mon Sep 17 00:00:00 2001 From: Lei Date: Wed, 27 Sep 2023 08:28:57 -0700 Subject: [PATCH] Support dynamic secrets (#10797) * support dynamic secrets config for cl node * wrap as func opt and fix tests * remove legacy field * add back the legacyURL for automation only --------- Co-authored-by: skudasov --- integration-tests/docker/test_env/cl_node.go | 25 +++++++++++++------ integration-tests/docker/test_env/test_env.go | 4 ++- .../docker/test_env/test_env_builder.go | 10 ++++++-- integration-tests/smoke/automation_test.go | 11 +++++++- integration-tests/utils/templates/secrets.go | 14 +++++++---- 5 files changed, 47 insertions(+), 17 deletions(-) diff --git a/integration-tests/docker/test_env/cl_node.go b/integration-tests/docker/test_env/cl_node.go index e4182ca4c36..d6ebaa69d81 100644 --- a/integration-tests/docker/test_env/cl_node.go +++ b/integration-tests/docker/test_env/cl_node.go @@ -58,6 +58,12 @@ type ClNode struct { type ClNodeOption = func(c *ClNode) +func WithSecrets(secretsTOML string) ClNodeOption { + return func(c *ClNode) { + c.NodeSecretsConfigTOML = secretsTOML + } +} + // Sets custom node container name if name is not empty func WithNodeContainerName(name string) ClNodeOption { return func(c *ClNode) { @@ -237,17 +243,20 @@ func (n *ClNode) StartContainer() error { if err != nil { return err } + + // If the node secrets TOML is not set, generate it with the default template nodeSecretsToml, err := templates.NodeSecretsTemplate{ - PgDbName: n.PostgresDb.DbName, - PgHost: n.PostgresDb.ContainerName, - PgPort: n.PostgresDb.Port, - PgPassword: n.PostgresDb.Password, + PgDbName: n.PostgresDb.DbName, + PgHost: n.PostgresDb.ContainerName, + PgPort: n.PostgresDb.Port, + PgPassword: n.PostgresDb.Password, + CustomSecrets: n.NodeSecretsConfigTOML, }.String() if err != nil { return err } - n.NodeSecretsConfigTOML = nodeSecretsToml - cReq, err := n.getContainerRequest() + + cReq, err := n.getContainerRequest(nodeSecretsToml) if err != nil { return err } @@ -302,7 +311,7 @@ func (n *ClNode) StartContainer() error { return nil } -func (n *ClNode) getContainerRequest() ( +func (n *ClNode) getContainerRequest(secrets string) ( *tc.ContainerRequest, error) { configFile, err := os.CreateTemp("", "node_config") if err != nil { @@ -320,7 +329,7 @@ func (n *ClNode) getContainerRequest() ( if err != nil { return nil, err } - _, err = secretsFile.WriteString(n.NodeSecretsConfigTOML) + _, err = secretsFile.WriteString(secrets) if err != nil { return nil, err } diff --git a/integration-tests/docker/test_env/test_env.go b/integration-tests/docker/test_env/test_env.go index 8c4faadbd2b..e3a9037da2c 100644 --- a/integration-tests/docker/test_env/test_env.go +++ b/integration-tests/docker/test_env/test_env.go @@ -24,6 +24,7 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/docker/test_env" "github.com/smartcontractkit/chainlink-testing-framework/logging" "github.com/smartcontractkit/chainlink-testing-framework/logwatch" + "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" "github.com/smartcontractkit/chainlink/integration-tests/client" @@ -154,7 +155,7 @@ func (te *CLClusterTestEnv) GetAPIs() []*client.ChainlinkClient { } // StartClNodes start one bootstrap node and {count} OCR nodes -func (te *CLClusterTestEnv) StartClNodes(nodeConfig *chainlink.Config, count int) error { +func (te *CLClusterTestEnv) StartClNodes(nodeConfig *chainlink.Config, count int, secretsConfig string) error { eg := &errgroup.Group{} nodes := make(chan *ClNode, count) @@ -168,6 +169,7 @@ func (te *CLClusterTestEnv) StartClNodes(nodeConfig *chainlink.Config, count int dbContainerName = te.Cfg.Nodes[nodeIndex].DbContainerName } n := NewClNode([]string{te.Network.Name}, nodeConfig, + WithSecrets(secretsConfig), WithNodeContainerName(nodeContainerName), WithDbContainerName(dbContainerName), ) diff --git a/integration-tests/docker/test_env/test_env_builder.go b/integration-tests/docker/test_env/test_env_builder.go index f3944b0ba96..19fd49fe11a 100644 --- a/integration-tests/docker/test_env/test_env_builder.go +++ b/integration-tests/docker/test_env/test_env_builder.go @@ -27,6 +27,7 @@ type CLTestEnvBuilder struct { hasMockServer bool hasForwarders bool clNodeConfig *chainlink.Config + secretsConfig string nonDevGethNetworks []blockchain.EVMNetwork clNodesCount int externalAdapterCount int @@ -87,6 +88,11 @@ func (b *CLTestEnvBuilder) WithCLNodeConfig(cfg *chainlink.Config) *CLTestEnvBui return b } +func (b *CLTestEnvBuilder) WithSecretsConfig(secrets string) *CLTestEnvBuilder { + b.secretsConfig = secrets + return b +} + func (b *CLTestEnvBuilder) WithMockServer(externalAdapterCount int) *CLTestEnvBuilder { b.hasMockServer = true b.externalAdapterCount = externalAdapterCount @@ -171,7 +177,7 @@ func (b *CLTestEnvBuilder) buildNewEnv(cfg *TestEnvConfig) (*CLClusterTestEnv, e return nil, errors.New("cannot create nodes with custom config without nonDevNetworks") } - err = te.StartClNodes(b.clNodeConfig, b.clNodesCount) + err = te.StartClNodes(b.clNodeConfig, b.clNodesCount, b.secretsConfig) if err != nil { return nil, err } @@ -233,7 +239,7 @@ func (b *CLTestEnvBuilder) buildNewEnv(cfg *TestEnvConfig) (*CLClusterTestEnv, e node.SetChainConfig(cfg, wsUrls, httpUrls, networkConfig, b.hasForwarders) - err := te.StartClNodes(cfg, b.clNodesCount) + err := te.StartClNodes(cfg, b.clNodesCount, b.secretsConfig) if err != nil { return nil, err } diff --git a/integration-tests/smoke/automation_test.go b/integration-tests/smoke/automation_test.go index 76ee75b21ba..0eabac7844b 100644 --- a/integration-tests/smoke/automation_test.go +++ b/integration-tests/smoke/automation_test.go @@ -1005,13 +1005,22 @@ func setupAutomationTestDocker( clNodeConfig.P2P.V2.AnnounceAddresses = &[]string{"0.0.0.0:6690"} clNodeConfig.P2P.V2.ListenAddresses = &[]string{"0.0.0.0:6690"} - // launch the environment + secretsConfig := ` + [Mercury.Credentials.cred1] + LegacyURL = 'http://localhost:53299' + URL = 'http://localhost:53299' + Username = 'node' + Password = 'nodepass' + ` + + //launch the environment env, err := test_env.NewCLTestEnvBuilder(). WithTestLogger(t). WithGeth(). WithMockServer(1). WithCLNodes(5). WithCLNodeConfig(clNodeConfig). + WithSecretsConfig(secretsConfig). WithFunding(big.NewFloat(.5)). Build() require.NoError(t, err, "Error deploying test environment") diff --git a/integration-tests/utils/templates/secrets.go b/integration-tests/utils/templates/secrets.go index 3d3f9e44a90..f81287e871f 100644 --- a/integration-tests/utils/templates/secrets.go +++ b/integration-tests/utils/templates/secrets.go @@ -8,10 +8,11 @@ import ( // NodeSecretsTemplate are used as text templates because of secret redacted fields of chainlink.Secrets // secret fields can't be marshalled as a plain text type NodeSecretsTemplate struct { - PgDbName string - PgHost string - PgPort string - PgPassword string + PgDbName string + PgHost string + PgPort string + PgPassword string + CustomSecrets string } func (c NodeSecretsTemplate) String() (string, error) { @@ -22,11 +23,14 @@ URL = 'postgresql://postgres:{{ .PgPassword }}@{{ .PgHost }}:{{ .PgPort }}/{{ .P [Password] Keystore = '................' # Required +{{ if .CustomSecrets }} + {{ .CustomSecrets }} +{{ else }} [Mercury.Credentials.cred1] -# URL = 'http://host.docker.internal:3000/reports' URL = 'localhost:1338' Username = 'node' Password = 'nodepass' +{{ end }} ` return templates.MarshalTemplate(c, uuid.NewString(), tpl) }