-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
chainlink_k8s.go
150 lines (137 loc) · 4.53 KB
/
chainlink_k8s.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// Package client enables interaction with APIs of test components like the mockserver and Chainlink nodes
package client
import (
"os"
"regexp"
"github.com/rs/zerolog/log"
"github.com/smartcontractkit/chainlink-testing-framework/k8s/environment"
)
type ChainlinkK8sClient struct {
ChartName string
PodName string
*ChainlinkClient
}
// NewChainlink creates a new Chainlink model using a provided config
func NewChainlinkK8sClient(c *ChainlinkConfig, podName, chartName string) (*ChainlinkK8sClient, error) {
rc, err := initRestyClient(c.URL, c.Email, c.Password, c.HTTPTimeout)
if err != nil {
return nil, err
}
_, isSet := os.LookupEnv("CL_CLIENT_DEBUG")
if isSet {
rc.SetDebug(true)
}
return &ChainlinkK8sClient{
ChainlinkClient: &ChainlinkClient{
APIClient: rc,
pageSize: 25,
Config: c,
},
ChartName: chartName,
PodName: podName,
}, nil
}
// UpgradeVersion upgrades the chainlink node to the new version
// Note: You need to call Run() on the test environment for changes to take effect
// Note: This function is not thread safe, call from a single thread
func (c *ChainlinkK8sClient) UpgradeVersion(testEnvironment *environment.Environment, newImage, newVersion string) error {
log.Info().
Str("Chart Name", c.ChartName).
Str("New Image", newImage).
Str("New Version", newVersion).
Msg("Upgrading Chainlink Node")
upgradeVals := map[string]any{
"chainlink": map[string]any{
"image": map[string]any{
"image": newImage,
"version": newVersion,
},
},
}
_, err := testEnvironment.UpdateHelm(c.ChartName, upgradeVals)
return err
}
// Name Chainlink instance chart/service name
func (c *ChainlinkK8sClient) Name() string {
return c.ChartName
}
func parseHostname(s string) string {
r := regexp.MustCompile(`://(?P<Host>.*):`)
return r.FindStringSubmatch(s)[1]
}
// ConnectChainlinkNodes creates new Chainlink clients
func ConnectChainlinkNodes(e *environment.Environment) ([]*ChainlinkK8sClient, error) {
var clients []*ChainlinkK8sClient
for _, nodeDetails := range e.ChainlinkNodeDetails {
c, err := NewChainlinkK8sClient(&ChainlinkConfig{
URL: nodeDetails.LocalIP,
Email: "notreal@fakeemail.ch",
Password: "fj293fbBnlQ!f9vNs",
InternalIP: parseHostname(nodeDetails.InternalIP),
}, nodeDetails.PodName, nodeDetails.ChartName)
if err != nil {
return nil, err
}
log.Debug().
Str("URL", c.Config.URL).
Str("Internal IP", c.Config.InternalIP).
Str("Chart Name", nodeDetails.ChartName).
Str("Pod Name", nodeDetails.PodName).
Msg("Connected to Chainlink node")
clients = append(clients, c)
}
return clients, nil
}
// ReconnectChainlinkNodes reconnects to Chainlink nodes after they have been modified, say through a Helm upgrade
// Note: Experimental as of now, will likely not work predictably.
func ReconnectChainlinkNodes(testEnvironment *environment.Environment, nodes []*ChainlinkK8sClient) (err error) {
for _, node := range nodes {
for _, details := range testEnvironment.ChainlinkNodeDetails {
if details.ChartName == node.ChartName { // Make the link from client to pod consistent
node, err = NewChainlinkK8sClient(&ChainlinkConfig{
URL: details.LocalIP,
Email: "notreal@fakeemail.ch",
Password: "fj293fbBnlQ!f9vNs",
InternalIP: parseHostname(details.InternalIP),
}, details.PodName, details.ChartName)
if err != nil {
return err
}
log.Debug().
Str("URL", node.Config.URL).
Str("Internal IP", node.Config.InternalIP).
Str("Chart Name", node.ChartName).
Str("Pod Name", node.PodName).
Msg("Reconnected to Chainlink node")
}
}
}
return nil
}
// ConnectChainlinkNodeURLs creates new Chainlink clients based on just URLs, should only be used inside K8s tests
func ConnectChainlinkNodeURLs(urls []string) ([]*ChainlinkK8sClient, error) {
var clients []*ChainlinkK8sClient
for _, url := range urls {
c, err := ConnectChainlinkNodeURL(url)
if err != nil {
return nil, err
}
clients = append(clients, c)
}
return clients, nil
}
// ConnectChainlinkNodeURL creates a new Chainlink client based on just a URL, should only be used inside K8s tests
func ConnectChainlinkNodeURL(url string) (*ChainlinkK8sClient, error) {
return NewChainlinkK8sClient(&ChainlinkConfig{
URL: url,
Email: "notreal@fakeemail.ch",
Password: "fj293fbBnlQ!f9vNs",
InternalIP: parseHostname(url),
},
parseHostname(url), // a decent guess
"connectedNodeByURL", // an intentionally bad decision
)
}
func (c *ChainlinkK8sClient) GetConfig() ChainlinkConfig {
return *c.Config
}