mirror of
https://github.com/netbirdio/netbird.git
synced 2025-04-17 16:08:47 +02:00
119 lines
3.7 KiB
Go
119 lines
3.7 KiB
Go
package internal
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"github.com/cenkalti/backoff/v4"
|
|
"github.com/google/uuid"
|
|
log "github.com/sirupsen/logrus"
|
|
"github.com/wiretrustee/wiretrustee/client/system"
|
|
mgm "github.com/wiretrustee/wiretrustee/management/client"
|
|
mgmProto "github.com/wiretrustee/wiretrustee/management/proto"
|
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
|
"google.golang.org/grpc/codes"
|
|
"google.golang.org/grpc/status"
|
|
)
|
|
|
|
func Login(ctx context.Context, config *Config, setupKey string) error {
|
|
backOff := &backoff.ExponentialBackOff{
|
|
InitialInterval: time.Second,
|
|
RandomizationFactor: backoff.DefaultRandomizationFactor,
|
|
Multiplier: backoff.DefaultMultiplier,
|
|
MaxInterval: 2 * time.Second,
|
|
MaxElapsedTime: time.Second * 10,
|
|
Stop: backoff.Stop,
|
|
Clock: backoff.SystemClock,
|
|
}
|
|
|
|
// validate our peer's Wireguard PRIVATE key
|
|
myPrivateKey, err := wgtypes.ParseKey(config.PrivateKey)
|
|
if err != nil {
|
|
log.Errorf("failed parsing Wireguard key %s: [%s]", config.PrivateKey, err.Error())
|
|
return err
|
|
}
|
|
|
|
var mgmTlsEnabled bool
|
|
if config.ManagementURL.Scheme == "https" {
|
|
mgmTlsEnabled = true
|
|
}
|
|
|
|
loginOp := func() error {
|
|
log.Debugf("connecting to Management Service %s", config.ManagementURL.String())
|
|
mgmClient, err := mgm.NewClient(ctx, config.ManagementURL.Host, myPrivateKey, mgmTlsEnabled)
|
|
if err != nil {
|
|
log.Errorf("failed connecting to Management Service %s %v", config.ManagementURL.String(), err)
|
|
return err
|
|
}
|
|
log.Debugf("connected to management Service %s", config.ManagementURL.String())
|
|
|
|
serverKey, err := mgmClient.GetServerPublicKey()
|
|
if err != nil {
|
|
log.Errorf("failed while getting Management Service public key: %v", err)
|
|
return err
|
|
}
|
|
|
|
_, err = loginPeer(*serverKey, mgmClient, setupKey)
|
|
if err != nil {
|
|
log.Errorf("failed logging-in peer on Management Service : %v", err)
|
|
return err
|
|
}
|
|
|
|
err = mgmClient.Close()
|
|
if err != nil {
|
|
log.Errorf("failed closing Management Service client: %v", err)
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
err = backoff.RetryNotify(loginOp, backOff, func(err error, duration time.Duration) {
|
|
log.Warnf("retrying Login to the Management service in %v due to error %v", duration, err)
|
|
})
|
|
if err != nil {
|
|
log.Errorf("exiting login retry loop due to unrecoverable error: %v", err)
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// loginPeer attempts to login to Management Service. If peer wasn't registered, tries the registration flow.
|
|
func loginPeer(serverPublicKey wgtypes.Key, client *mgm.GrpcClient, setupKey string) (*mgmProto.LoginResponse, error) {
|
|
loginResp, err := client.Login(serverPublicKey)
|
|
if err != nil {
|
|
if s, ok := status.FromError(err); ok && s.Code() == codes.PermissionDenied {
|
|
log.Debugf("peer registration required")
|
|
return registerPeer(serverPublicKey, client, setupKey)
|
|
} else {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
log.Info("peer has successfully logged-in to Management Service")
|
|
|
|
return loginResp, nil
|
|
}
|
|
|
|
// registerPeer checks whether setupKey was provided via cmd line and if not then it prompts user to enter a key.
|
|
// Otherwise tries to register with the provided setupKey via command line.
|
|
func registerPeer(serverPublicKey wgtypes.Key, client *mgm.GrpcClient, setupKey string) (*mgmProto.LoginResponse, error) {
|
|
validSetupKey, err := uuid.Parse(setupKey)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
log.Debugf("sending peer registration request to Management Service")
|
|
info := system.GetInfo()
|
|
loginResp, err := client.Register(serverPublicKey, validSetupKey.String(), info)
|
|
if err != nil {
|
|
log.Errorf("failed registering peer %v", err)
|
|
return nil, err
|
|
}
|
|
|
|
log.Infof("peer has been successfully registered on Management Service")
|
|
|
|
return loginResp, nil
|
|
}
|