github.com/smartcontractkit/chainlink-testing-framework/libs@v0.0.0-20240227141906-ec710b4eb1a3/k8s/pkg/helm/chainlink/chainlink.go (about) 1 package chainlink 2 3 import ( 4 "fmt" 5 "os" 6 "strconv" 7 8 "github.com/rs/zerolog/log" 9 10 "github.com/smartcontractkit/chainlink-testing-framework/libs/k8s/client" 11 "github.com/smartcontractkit/chainlink-testing-framework/libs/k8s/config" 12 "github.com/smartcontractkit/chainlink-testing-framework/libs/k8s/environment" 13 "github.com/smartcontractkit/chainlink-testing-framework/libs/utils/projectpath" 14 ) 15 16 const ( 17 AppName = "chainlink" 18 NodesLocalURLsKey = "chainlink_local" 19 NodesInternalURLsKey = "chainlink_internal" 20 DBsLocalURLsKey = "chainlink_db" 21 ) 22 23 type Props struct { 24 HasReplicas bool 25 } 26 27 type Chart struct { 28 Name string 29 Index int 30 Path string 31 Version string 32 Props *Props 33 Values *map[string]any 34 } 35 36 func (m Chart) IsDeploymentNeeded() bool { 37 return true 38 } 39 40 func (m Chart) GetName() string { 41 return m.Name 42 } 43 44 func (m Chart) GetPath() string { 45 return m.Path 46 } 47 48 func (m Chart) GetVersion() string { 49 return m.Version 50 } 51 52 func (m Chart) GetProps() any { 53 return m.Props 54 } 55 56 func (m Chart) GetValues() *map[string]any { 57 return m.Values 58 } 59 60 func (m Chart) ExportData(e *environment.Environment) error { 61 // fetching all apps with label app=chainlink-${deploymentIndex}:${instanceIndex} 62 pods, err := e.Fwd.Client.ListPods(e.Cfg.Namespace, fmt.Sprintf("app=%s", m.Name)) 63 if err != nil { 64 return err 65 } 66 for i := 0; i < len(pods.Items); i++ { 67 chainlinkNode := fmt.Sprintf("%s:node-%d", m.Name, i+1) 68 pgNode := fmt.Sprintf("%s-postgres:node-%d", m.Name, i+1) 69 internalConnection, err := e.Fwd.FindPort(chainlinkNode, "node", "access").As(client.RemoteConnection, client.HTTP) 70 if err != nil { 71 return err 72 } 73 if !m.Props.HasReplicas { 74 services, err := e.Client.ListServices(e.Cfg.Namespace, fmt.Sprintf("app=%s", m.Name)) 75 if err != nil { 76 return err 77 } 78 if services != nil && len(services.Items) > 0 { 79 internalConnection = fmt.Sprintf("http://%s:6688", services.Items[0].Name) 80 } 81 } 82 83 var localConnection string 84 if e.Cfg.InsideK8s { 85 localConnection = internalConnection 86 } else { 87 localConnection, err = e.Fwd.FindPort(chainlinkNode, "node", "access").As(client.LocalConnection, client.HTTP) 88 if err != nil { 89 return err 90 } 91 } 92 e.URLs[NodesInternalURLsKey] = append(e.URLs[NodesInternalURLsKey], internalConnection) 93 e.URLs[NodesLocalURLsKey] = append(e.URLs[NodesLocalURLsKey], localConnection) 94 95 dbLocalConnection, err := e.Fwd.FindPort(pgNode, "chainlink-db", "postgres"). 96 As(client.LocalConnection, client.HTTP) 97 if err != nil { 98 return err 99 } 100 e.URLs[DBsLocalURLsKey] = append(e.URLs[DBsLocalURLsKey], dbLocalConnection) 101 log.Debug(). 102 Str("Chart Name", m.Name). 103 Str("Local IP", localConnection). 104 Str("Local DB IP", dbLocalConnection). 105 Str("K8s Internal Connection", internalConnection). 106 Msg("Chainlink Node Details") 107 108 nodeDetails := &environment.ChainlinkNodeDetail{ 109 ChartName: m.Name, 110 PodName: pods.Items[i].Name, 111 LocalIP: localConnection, 112 InternalIP: internalConnection, 113 DBLocalIP: dbLocalConnection, 114 } 115 e.ChainlinkNodeDetails = append(e.ChainlinkNodeDetails, nodeDetails) 116 } 117 return nil 118 } 119 120 func defaultProps() map[string]any { 121 internalRepo := os.Getenv(config.EnvVarInternalDockerRepo) 122 chainlinkImage := "public.ecr.aws/chainlink/chainlink" 123 postgresImage := "postgres" 124 if internalRepo != "" { 125 chainlinkImage = fmt.Sprintf("%s/chainlink", internalRepo) 126 postgresImage = fmt.Sprintf("%s/postgres", internalRepo) 127 } 128 env := make(map[string]string) 129 return map[string]any{ 130 "replicas": "1", 131 "env": env, 132 "chainlink": map[string]any{ 133 "image": map[string]any{ 134 "image": chainlinkImage, 135 "version": "develop", 136 }, 137 "web_port": "6688", 138 "p2p_port": "6690", 139 "resources": map[string]any{ 140 "requests": map[string]any{ 141 "cpu": "350m", 142 "memory": "1024Mi", 143 }, 144 "limits": map[string]any{ 145 "cpu": "350m", 146 "memory": "1024Mi", 147 }, 148 }, 149 }, 150 "db": map[string]any{ 151 "image": map[string]any{ 152 "image": postgresImage, 153 "version": "11.15", 154 }, 155 "stateful": false, 156 "capacity": "1Gi", 157 "resources": map[string]any{ 158 "requests": map[string]any{ 159 "cpu": "250m", 160 "memory": "256Mi", 161 }, 162 "limits": map[string]any{ 163 "cpu": "250m", 164 "memory": "256Mi", 165 }, 166 }, 167 }, 168 } 169 } 170 171 type OverrideFn = func(source interface{}, target interface{}) 172 173 func New(index int, props map[string]any) environment.ConnectedChart { 174 return NewVersioned(index, "", props, nil, func(_ interface{}, target interface{}) { 175 config.MustEnvOverrideVersion(target) 176 }) 177 } 178 179 // NewWithOverride enables you to pass in a function that will override the default properties 180 func NewWithOverride(index int, props map[string]any, overrideSource interface{}, overrideFn OverrideFn) environment.ConnectedChart { 181 return NewVersioned(index, "", props, overrideSource, overrideFn) 182 } 183 184 // NewVersioned enables you to select a specific helm chart version 185 func NewVersioned(index int, helmVersion string, props map[string]any, overrideSource interface{}, overrideFn OverrideFn) environment.ConnectedChart { 186 dp := defaultProps() 187 overrideFn(overrideSource, &dp) 188 config.MustMerge(&dp, props) 189 p := &Props{ 190 HasReplicas: false, 191 } 192 if props["replicas"] != nil && props["replicas"] != "1" { 193 p.HasReplicas = true 194 replicas := props["replicas"].(int) 195 var nodesMap []map[string]any 196 for i := 0; i < replicas; i++ { 197 nodesMap = append(nodesMap, map[string]any{ 198 "name": fmt.Sprintf("node-%d", i+1), 199 }) 200 } 201 dp["nodes"] = nodesMap 202 } 203 chartPath := "chainlink-qa/chainlink" 204 if b, err := strconv.ParseBool(os.Getenv(config.EnvVarLocalCharts)); err == nil && b { 205 chartPath = fmt.Sprintf("%s/chainlink", projectpath.ChartsRoot) 206 } 207 return Chart{ 208 Index: index, 209 Name: fmt.Sprintf("%s-%d", AppName, index), 210 Path: chartPath, 211 Version: helmVersion, 212 Values: &dp, 213 Props: p, 214 } 215 }