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  }