...

Source file src/edge-infra.dev/pkg/sds/etcd/operator/internal/config/config.go

Documentation: edge-infra.dev/pkg/sds/etcd/operator/internal/config

     1  // Package config provides functionality for the configuring the etcd operator's reconcilers
     2  package config
     3  
     4  import (
     5  	"context"
     6  	"fmt"
     7  	"net"
     8  	"strings"
     9  	"time"
    10  
    11  	"github.com/spf13/afero"
    12  	clientv3 "go.etcd.io/etcd/client/v3"
    13  	v1 "k8s.io/api/core/v1"
    14  	ctrl "sigs.k8s.io/controller-runtime"
    15  	k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
    16  
    17  	calico "edge-infra.dev/pkg/k8s/net/calico"
    18  	nodemeta "edge-infra.dev/pkg/sds/ien/node"
    19  	"edge-infra.dev/pkg/sds/lib/etcd/client"
    20  	etcdretryclient "edge-infra.dev/pkg/sds/lib/etcd/client/retry"
    21  	kuberetryclient "edge-infra.dev/pkg/sds/lib/k8s/retryclient"
    22  	kubeclienttypes "edge-infra.dev/pkg/sds/lib/k8s/retryclient/types"
    23  	"edge-infra.dev/pkg/sds/lib/os/file"
    24  )
    25  
    26  const (
    27  	Worker       = "worker"
    28  	ControlPlane = "controlplane"
    29  )
    30  
    31  // Config contains basic configuration for the reconciler and embeds the clients
    32  type Config struct {
    33  	Name            string
    34  	NodeName        string
    35  	Mgr             ctrl.Manager
    36  	EtcdRetryClient etcdretryclient.Retrier
    37  	KubeRetryClient kubeclienttypes.Retrier
    38  	Fs              afero.Fs
    39  }
    40  
    41  // WithDefaultKubeRetryClient sets the default retry client for the config with the
    42  // manager's client and reader.
    43  func (c *Config) WithDefaultKubeRetryClient() {
    44  	c.KubeRetryClient = kuberetryclient.New(c.Mgr.GetClient(), c.Mgr.GetAPIReader(), kuberetryclient.Config{})
    45  }
    46  
    47  // WithDefaultEtcdRetryClient sets the default retry client for the config. The
    48  // default retry client will retry requests every 2 seconds, each request will
    49  // timeout after 2 seconds, and the client will retry for a total of 2 seconds
    50  func (c *Config) WithDefaultEtcdRetryClient(ctx context.Context) error {
    51  	client, err := createEtcdClient(ctx, c.Mgr.GetClient())
    52  	if err != nil {
    53  		return err
    54  	}
    55  	config := etcdretryclient.Config{}
    56  	c.EtcdRetryClient = etcdretryclient.New(*client, config)
    57  	return nil
    58  }
    59  
    60  // createEtcdClient creates a new etcd client using the manager's kubernetes client
    61  // to get the etcd IP address
    62  func createEtcdClient(ctx context.Context, kubeClient k8sclient.Client) (*clientv3.Client, error) {
    63  	config, err := client.NewTLSConfig(file.New())
    64  	if err != nil {
    65  		return nil, fmt.Errorf("failed to create etcd tls config: %w", err)
    66  	}
    67  
    68  	address, err := getEtcdAddress(ctx, kubeClient)
    69  	if err != nil {
    70  		return nil, fmt.Errorf("failed to get etcd IP address: %w", err)
    71  	}
    72  
    73  	clientURL := net.JoinHostPort(address, "2379")
    74  	return client.New(config, 5*time.Second, clientURL)
    75  }
    76  
    77  // getEtcdAddress gets the IP address of the controlplane's etcd pod
    78  func getEtcdAddress(ctx context.Context, client k8sclient.Client) (string, error) { // ([]*net.IP, error) {
    79  	nodeList := &v1.NodeList{}
    80  	if err := client.List(ctx, nodeList); err != nil {
    81  		return "", err
    82  	}
    83  
    84  	// find the controlplane node and return the IP address
    85  	for _, node := range nodeList.Items {
    86  		if strings.Contains(node.GetLabels()[nodemeta.RoleLabel], ControlPlane) {
    87  			IPAddress, err := calico.ParseNodeIPs(node)
    88  			if err != nil {
    89  				return "", err
    90  			}
    91  
    92  			return IPAddress[0].String(), nil
    93  		}
    94  	}
    95  	return "", fmt.Errorf("failed to fine a node with label %v: %v", nodemeta.RoleLabel, ControlPlane)
    96  }
    97  

View as plain text