mirror of
https://github.com/kubenetworks/kubevpn.git
synced 2025-09-26 19:31:17 +08:00
feat: support restore from local config (#645)
* refactor: optimize dhcp * feat: support recover from config * feat: optimize code * feat: fix bug * feat: fix bug * feat: rename
This commit is contained in:
@@ -267,9 +267,9 @@ func GetClusterIDByConfig(cmd *cobra.Command, config Config) (string, error) {
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
err = c.InitDHCP(cmd.Context())
|
||||
id, err := util.GetClusterID(cmd.Context(), c.GetClientset().CoreV1().Namespaces(), ns)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return c.GetClusterID(), nil
|
||||
return string(id), nil
|
||||
}
|
||||
|
@@ -24,6 +24,8 @@ const (
|
||||
ConfigFile = "config.yaml"
|
||||
|
||||
TmpDir = "tmp"
|
||||
|
||||
DBFile = "db"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -107,3 +109,7 @@ func GetDaemonLogPath(isSudo bool) string {
|
||||
func GetPProfPath() string {
|
||||
return filepath.Join(daemonPath, PProfDir)
|
||||
}
|
||||
|
||||
func GetDBPath() string {
|
||||
return filepath.Join(daemonPath, DBFile)
|
||||
}
|
||||
|
@@ -90,6 +90,7 @@ func (svr *Server) Clone(resp rpc.Daemon_CloneServer) (err error) {
|
||||
TargetWorkloadNames: map[string]string{},
|
||||
LocalDir: req.LocalDir,
|
||||
RemoteDir: req.RemoteDir,
|
||||
Request: req,
|
||||
}
|
||||
file, err := util.ConvertToTempKubeconfigFile([]byte(req.KubeconfigBytes))
|
||||
if err != nil {
|
||||
|
@@ -5,6 +5,7 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/pkg/errors"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"google.golang.org/grpc"
|
||||
@@ -18,6 +19,14 @@ import (
|
||||
)
|
||||
|
||||
func (svr *Server) ConnectFork(resp rpc.Daemon_ConnectForkServer) (err error) {
|
||||
if !svr.IsSudo {
|
||||
defer func() {
|
||||
if err == nil {
|
||||
svr.OffloadToConfig()
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
req, err := resp.Recv()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -38,6 +47,7 @@ func (svr *Server) ConnectFork(resp rpc.Daemon_ConnectForkServer) (err error) {
|
||||
Lock: &svr.Lock,
|
||||
Image: req.Image,
|
||||
ImagePullSecretName: req.ImagePullSecretName,
|
||||
Request: proto.Clone(req).(*rpc.ConnectRequest),
|
||||
}
|
||||
file, err := util.ConvertToTempKubeconfigFile([]byte(req.KubeconfigBytes))
|
||||
if err != nil {
|
||||
@@ -100,6 +110,7 @@ func (svr *Server) redirectConnectForkToSudoDaemon(req *rpc.ConnectRequest, resp
|
||||
ExtraRouteInfo: *handler.ParseExtraRouteFromRPC(req.ExtraRoute),
|
||||
Engine: config.Engine(req.Engine),
|
||||
OriginKubeconfigPath: req.OriginKubeconfigPath,
|
||||
Request: proto.Clone(req).(*rpc.ConnectRequest),
|
||||
}
|
||||
connect.AddRolloutFunc(func() error {
|
||||
sshCancel()
|
||||
@@ -152,7 +163,10 @@ func (svr *Server) redirectConnectForkToSudoDaemon(req *rpc.ConnectRequest, resp
|
||||
req.ManagerNamespace = req.Namespace
|
||||
}
|
||||
|
||||
for _, options := range svr.secondaryConnect {
|
||||
for _, options := range append(svr.secondaryConnect, svr.connect) {
|
||||
if options == nil {
|
||||
continue
|
||||
}
|
||||
isSameCluster, _ := util.IsSameCluster(
|
||||
sshCtx,
|
||||
options.GetClientset().CoreV1(), options.Namespace,
|
||||
@@ -166,7 +180,8 @@ func (svr *Server) redirectConnectForkToSudoDaemon(req *rpc.ConnectRequest, resp
|
||||
}
|
||||
}
|
||||
|
||||
ctx, err := connect.RentIP(resp.Context())
|
||||
var ipCtx context.Context
|
||||
ipCtx, err = connect.RentIP(resp.Context(), req.IPv4, req.IPv6)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -178,7 +193,7 @@ func (svr *Server) redirectConnectForkToSudoDaemon(req *rpc.ConnectRequest, resp
|
||||
}
|
||||
req.KubeconfigBytes = string(content)
|
||||
req.SshJump = ssh.SshConfig{}.ToRPC()
|
||||
connResp, err = cli.ConnectFork(ctx)
|
||||
connResp, err = cli.ConnectFork(ipCtx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@@ -6,6 +6,7 @@ import (
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/pkg/errors"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"google.golang.org/grpc"
|
||||
@@ -21,6 +22,14 @@ import (
|
||||
)
|
||||
|
||||
func (svr *Server) Connect(resp rpc.Daemon_ConnectServer) (err error) {
|
||||
if !svr.IsSudo {
|
||||
defer func() {
|
||||
if err == nil {
|
||||
svr.OffloadToConfig()
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
req, err := resp.Recv()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -55,6 +64,7 @@ func (svr *Server) Connect(resp rpc.Daemon_ConnectServer) (err error) {
|
||||
Lock: &svr.Lock,
|
||||
Image: req.Image,
|
||||
ImagePullSecretName: req.ImagePullSecretName,
|
||||
Request: proto.Clone(req).(*rpc.ConnectRequest),
|
||||
}
|
||||
var file string
|
||||
file, err = util.ConvertToTempKubeconfigFile([]byte(req.KubeconfigBytes))
|
||||
@@ -114,6 +124,7 @@ func (svr *Server) redirectToSudoDaemon(req *rpc.ConnectRequest, resp rpc.Daemon
|
||||
ExtraRouteInfo: *handler.ParseExtraRouteFromRPC(req.ExtraRoute),
|
||||
Engine: config.Engine(req.Engine),
|
||||
OriginKubeconfigPath: req.OriginKubeconfigPath,
|
||||
Request: proto.Clone(req).(*rpc.ConnectRequest),
|
||||
}
|
||||
connect.AddRolloutFunc(func() error {
|
||||
sshCancel()
|
||||
@@ -184,7 +195,8 @@ func (svr *Server) redirectToSudoDaemon(req *rpc.ConnectRequest, resp rpc.Daemon
|
||||
}
|
||||
}
|
||||
|
||||
ctx, err := connect.RentIP(resp.Context())
|
||||
var ipCtx context.Context
|
||||
ipCtx, err = connect.RentIP(resp.Context(), req.IPv4, req.IPv6)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -196,7 +208,7 @@ func (svr *Server) redirectToSudoDaemon(req *rpc.ConnectRequest, resp rpc.Daemon
|
||||
}
|
||||
req.KubeconfigBytes = string(content)
|
||||
req.SshJump = ssh.SshConfig{}.ToRPC()
|
||||
connResp, err = cli.Connect(ctx)
|
||||
connResp, err = cli.Connect(ipCtx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@@ -18,7 +18,15 @@ import (
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/util"
|
||||
)
|
||||
|
||||
func (svr *Server) Disconnect(resp rpc.Daemon_DisconnectServer) error {
|
||||
func (svr *Server) Disconnect(resp rpc.Daemon_DisconnectServer) (err error) {
|
||||
if !svr.IsSudo {
|
||||
defer func() {
|
||||
if err == nil {
|
||||
svr.OffloadToConfig()
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
req, err := resp.Recv()
|
||||
if err != nil {
|
||||
return err
|
||||
|
@@ -29,8 +29,9 @@ import (
|
||||
// 2. if already connect to cluster
|
||||
// 2.1 disconnect from cluster
|
||||
// 2.2 same as step 1
|
||||
func (svr *Server) Proxy(resp rpc.Daemon_ProxyServer) (e error) {
|
||||
req, err := resp.Recv()
|
||||
func (svr *Server) Proxy(resp rpc.Daemon_ProxyServer) (err error) {
|
||||
var req *rpc.ProxyRequest
|
||||
req, err = resp.Recv()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -39,7 +40,8 @@ func (svr *Server) Proxy(resp rpc.Daemon_ProxyServer) (e error) {
|
||||
ctx := plog.WithLogger(resp.Context(), logger)
|
||||
var sshConf = ssh.ParseSshFromRPC(req.SshJump)
|
||||
|
||||
file, err := util.ConvertToTempKubeconfigFile([]byte(req.KubeconfigBytes))
|
||||
var file string
|
||||
file, err = util.ConvertToTempKubeconfigFile([]byte(req.KubeconfigBytes))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -56,6 +58,7 @@ func (svr *Server) Proxy(resp rpc.Daemon_ProxyServer) (e error) {
|
||||
OriginKubeconfigPath: req.OriginKubeconfigPath,
|
||||
Image: req.Image,
|
||||
ImagePullSecretName: req.ImagePullSecretName,
|
||||
Request: convert(req),
|
||||
}
|
||||
err = connect.InitClient(util.InitFactoryByPath(file, req.Namespace))
|
||||
if err != nil {
|
||||
@@ -77,12 +80,13 @@ func (svr *Server) Proxy(resp rpc.Daemon_ProxyServer) (e error) {
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if e != nil && svr.connect != nil {
|
||||
if err != nil && svr.connect != nil {
|
||||
_ = svr.connect.LeaveAllProxyResources(plog.WithLogger(context.Background(), logger))
|
||||
}
|
||||
}()
|
||||
|
||||
cli, err := svr.GetClient(false)
|
||||
var cli rpc.DaemonClient
|
||||
cli, err = svr.GetClient(false)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "daemon is not available")
|
||||
}
|
||||
|
@@ -15,6 +15,8 @@ import (
|
||||
)
|
||||
|
||||
func (svr *Server) Quit(resp rpc.Daemon_QuitServer) error {
|
||||
defer svr.CleanupConfig()
|
||||
|
||||
logger := plog.GetLoggerForClient(int32(log.InfoLevel), io.MultiWriter(newQuitWarp(resp), svr.LogFile))
|
||||
ctx := context.Background()
|
||||
if resp != nil {
|
||||
|
@@ -38,6 +38,10 @@ func (svr *Server) Reset(resp rpc.Daemon_ResetServer) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
connect.Namespace, err = util.DetectManagerNamespace(ctx, connect.GetFactory(), req.Namespace)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = connect.Reset(ctx, req.Namespace, req.Workloads)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@@ -1,15 +1,21 @@
|
||||
package action
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"gopkg.in/natefinch/lumberjack.v2"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/metadata/metadatainformer"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/config"
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/daemon/rpc"
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/handler"
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/util"
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
@@ -31,3 +37,86 @@ type Server struct {
|
||||
|
||||
ID string
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
Connect *handler.ConnectOptions `json:"Connect"`
|
||||
SecondaryConnect []*handler.ConnectOptions `json:"SecondaryConnect"`
|
||||
}
|
||||
|
||||
func (svr *Server) LoadFromConfig() error {
|
||||
file, err := os.ReadFile(config.GetDBPath())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
jsonConf, err := yaml.YAMLToJSON(file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var conf Config
|
||||
err = json.Unmarshal(jsonConf, &conf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if conf.Connect == nil && len(conf.SecondaryConnect) == 0 {
|
||||
return nil
|
||||
}
|
||||
var client rpc.DaemonClient
|
||||
for {
|
||||
_, err = svr.GetClient(true)
|
||||
if err != nil {
|
||||
time.Sleep(time.Millisecond * 200)
|
||||
continue
|
||||
}
|
||||
client, err = svr.GetClient(false)
|
||||
if err != nil {
|
||||
time.Sleep(time.Millisecond * 200)
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
if conf.Connect != nil {
|
||||
var resp rpc.Daemon_ConnectClient
|
||||
resp, err = client.Connect(context.Background())
|
||||
if err == nil {
|
||||
conf.Connect.Request.IPv4 = conf.Connect.LocalTunIPv4.String()
|
||||
conf.Connect.Request.IPv6 = conf.Connect.LocalTunIPv6.String()
|
||||
err = resp.Send(conf.Connect.Request)
|
||||
_ = util.PrintGRPCStream[rpc.ConnectResponse](nil, resp, svr.LogFile)
|
||||
}
|
||||
}
|
||||
for _, conf := range append(conf.SecondaryConnect) {
|
||||
if conf != nil {
|
||||
var resp rpc.Daemon_ConnectClient
|
||||
resp, err = client.ConnectFork(context.Background())
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
conf.Request.IPv4 = conf.LocalTunIPv4.String()
|
||||
conf.Request.IPv6 = conf.LocalTunIPv6.String()
|
||||
err = resp.Send(conf.Request)
|
||||
_ = util.PrintGRPCStream[rpc.ConnectResponse](nil, resp, svr.LogFile)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (svr *Server) OffloadToConfig() error {
|
||||
conf := &Config{
|
||||
Connect: svr.connect,
|
||||
SecondaryConnect: svr.secondaryConnect,
|
||||
}
|
||||
jsonConf, err := json.Marshal(conf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
yamlConf, err := yaml.JSONToYAML(jsonConf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = os.WriteFile(config.GetDBPath(), yamlConf, 0644)
|
||||
return err
|
||||
}
|
||||
|
||||
func (svr *Server) CleanupConfig() error {
|
||||
return os.Remove(config.GetDBPath())
|
||||
}
|
||||
|
@@ -13,7 +13,9 @@ import (
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/util"
|
||||
)
|
||||
|
||||
func (svr *Server) Uninstall(resp rpc.Daemon_UninstallServer) error {
|
||||
func (svr *Server) Uninstall(resp rpc.Daemon_UninstallServer) (err error) {
|
||||
defer svr.CleanupConfig()
|
||||
|
||||
req, err := resp.Recv()
|
||||
if err != nil {
|
||||
return err
|
||||
|
@@ -124,6 +124,9 @@ func (o *SvrOption) Start(ctx context.Context) error {
|
||||
_ = l.Close()
|
||||
}
|
||||
o.svr = &action.Server{Cancel: cancel, IsSudo: o.IsSudo, GetClient: GetClient, LogFile: l, ID: o.ID}
|
||||
if !o.IsSudo {
|
||||
go o.svr.LoadFromConfig()
|
||||
}
|
||||
rpc.RegisterDaemonServer(svr, o.svr)
|
||||
return downgradingServer.Serve(lis)
|
||||
//return o.svr.Serve(lis)
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -63,6 +63,11 @@ message ConnectRequest {
|
||||
// 2. detect which namespace helm installed by (helm list -A), match app name==kubevpn and status is deployed
|
||||
// 3. otherwise, use options '-n' or '--namespace'
|
||||
string ManagerNamespace = 12;
|
||||
|
||||
// Inner ip v4 and v6, for recovery from local db,
|
||||
// this filed only set when recover from local db, otherwise, always empty
|
||||
string IPv4 = 13;
|
||||
string IPv6 = 14;
|
||||
}
|
||||
|
||||
message ConnectResponse {
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -21,16 +21,16 @@ import (
|
||||
)
|
||||
|
||||
type Manager struct {
|
||||
client *kubernetes.Clientset
|
||||
clientset *kubernetes.Clientset
|
||||
cidr *net.IPNet
|
||||
cidr6 *net.IPNet
|
||||
namespace string
|
||||
clusterID types.UID
|
||||
}
|
||||
|
||||
func NewDHCPManager(client *kubernetes.Clientset, namespace string) *Manager {
|
||||
func NewDHCPManager(clientset *kubernetes.Clientset, namespace string) *Manager {
|
||||
return &Manager{
|
||||
client: client,
|
||||
clientset: clientset,
|
||||
namespace: namespace,
|
||||
cidr: &net.IPNet{IP: config.RouterIP, Mask: config.CIDR.Mask},
|
||||
cidr6: &net.IPNet{IP: config.RouterIP6, Mask: config.CIDR6.Mask},
|
||||
@@ -38,15 +38,15 @@ func NewDHCPManager(client *kubernetes.Clientset, namespace string) *Manager {
|
||||
}
|
||||
|
||||
// InitDHCP
|
||||
// TODO optimize dhcp, using mac address, ip and deadline as unit
|
||||
// TODO optimize dhcp, using mac address, ipPair and deadline as unit
|
||||
func (m *Manager) InitDHCP(ctx context.Context) error {
|
||||
cm, err := m.client.CoreV1().ConfigMaps(m.namespace).Get(ctx, config.ConfigMapPodTrafficManager, metav1.GetOptions{})
|
||||
cm, err := m.clientset.CoreV1().ConfigMaps(m.namespace).Get(ctx, config.ConfigMapPodTrafficManager, metav1.GetOptions{})
|
||||
if err != nil && !apierrors.IsNotFound(err) {
|
||||
return fmt.Errorf("failed to get configmap %s, err: %v", config.ConfigMapPodTrafficManager, err)
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
m.clusterID, err = util.GetClusterID(ctx, m.client.CoreV1().Namespaces(), m.namespace)
|
||||
m.clusterID, err = util.GetClusterID(ctx, m.clientset.CoreV1().Namespaces(), m.namespace)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -63,11 +63,11 @@ func (m *Manager) InitDHCP(ctx context.Context) error {
|
||||
config.KeyClusterIPv4POOLS: "",
|
||||
},
|
||||
}
|
||||
cm, err = m.client.CoreV1().ConfigMaps(m.namespace).Create(ctx, cm, metav1.CreateOptions{})
|
||||
cm, err = m.clientset.CoreV1().ConfigMaps(m.namespace).Create(ctx, cm, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create configmap: %v", err)
|
||||
}
|
||||
m.clusterID, err = util.GetClusterID(ctx, m.client.CoreV1().Namespaces(), m.namespace)
|
||||
m.clusterID, err = util.GetClusterID(ctx, m.clientset.CoreV1().Namespaces(), m.namespace)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -86,6 +86,7 @@ func (m *Manager) RentIP(ctx context.Context) (*net.IPNet, *net.IPNet, error) {
|
||||
}
|
||||
return false
|
||||
}
|
||||
var uselessIPs []net.IP
|
||||
var v4, v6 net.IP
|
||||
err := m.updateDHCPConfigMap(ctx, func(ipv4 *ipallocator.Range, ipv6 *ipallocator.Range) (err error) {
|
||||
for {
|
||||
@@ -95,6 +96,7 @@ func (m *Manager) RentIP(ctx context.Context) (*net.IPNet, *net.IPNet, error) {
|
||||
if !isAlreadyExistedFunc(v4) {
|
||||
break
|
||||
}
|
||||
uselessIPs = append(uselessIPs, v4)
|
||||
}
|
||||
for {
|
||||
if v6, err = ipv6.AllocateNext(); err != nil {
|
||||
@@ -103,9 +105,15 @@ func (m *Manager) RentIP(ctx context.Context) (*net.IPNet, *net.IPNet, error) {
|
||||
if !isAlreadyExistedFunc(v6) {
|
||||
break
|
||||
}
|
||||
uselessIPs = append(uselessIPs, v6)
|
||||
}
|
||||
return
|
||||
})
|
||||
if len(uselessIPs) != 0 {
|
||||
if er := m.releaseIP(ctx, uselessIPs...); er != nil {
|
||||
plog.G(ctx).Errorf("Failed to release useless IPs: %v", er)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
plog.G(ctx).Errorf("Failed to rent IP from DHCP server: %v", err)
|
||||
return nil, nil, err
|
||||
@@ -113,28 +121,44 @@ func (m *Manager) RentIP(ctx context.Context) (*net.IPNet, *net.IPNet, error) {
|
||||
return &net.IPNet{IP: v4, Mask: m.cidr.Mask}, &net.IPNet{IP: v6, Mask: m.cidr6.Mask}, nil
|
||||
}
|
||||
|
||||
func (m *Manager) ReleaseIP(ctx context.Context, ips ...net.IP) error {
|
||||
func (m *Manager) ReleaseIP(ctx context.Context, v4, v6 net.IP) error {
|
||||
return retry.RetryOnConflict(retry.DefaultRetry, func() error {
|
||||
return m.updateDHCPConfigMap(ctx, func(ipv4 *ipallocator.Range, ipv6 *ipallocator.Range) error {
|
||||
if err := ipv4.Release(v4); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := ipv6.Release(v6); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func (m *Manager) releaseIP(ctx context.Context, ips ...net.IP) error {
|
||||
if len(ips) == 0 {
|
||||
return nil
|
||||
}
|
||||
return m.updateDHCPConfigMap(ctx, func(ipv4 *ipallocator.Range, ipv6 *ipallocator.Range) error {
|
||||
for _, ip := range ips {
|
||||
var err error
|
||||
if ip.To4() != nil {
|
||||
err = ipv4.Release(ip)
|
||||
} else {
|
||||
err = ipv6.Release(ip)
|
||||
return retry.RetryOnConflict(retry.DefaultRetry, func() error {
|
||||
return m.updateDHCPConfigMap(ctx, func(ipv4 *ipallocator.Range, ipv6 *ipallocator.Range) error {
|
||||
for _, ip := range ips {
|
||||
var err error
|
||||
if ip.To4() != nil {
|
||||
err = ipv4.Release(ip)
|
||||
} else {
|
||||
err = ipv6.Release(ip)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return nil
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func (m *Manager) updateDHCPConfigMap(ctx context.Context, f func(ipv4 *ipallocator.Range, ipv6 *ipallocator.Range) error) error {
|
||||
cm, err := m.client.CoreV1().ConfigMaps(m.namespace).Get(ctx, config.ConfigMapPodTrafficManager, metav1.GetOptions{})
|
||||
cm, err := m.clientset.CoreV1().ConfigMaps(m.namespace).Get(ctx, config.ConfigMapPodTrafficManager, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get configmap DHCP server, err: %v", err)
|
||||
}
|
||||
@@ -189,38 +213,15 @@ func (m *Manager) updateDHCPConfigMap(ctx context.Context, f func(ipv4 *ipalloca
|
||||
return err
|
||||
}
|
||||
cm.Data[config.KeyDHCP6] = base64.StdEncoding.EncodeToString(bytes)
|
||||
_, err = m.client.CoreV1().ConfigMaps(m.namespace).Update(ctx, cm, metav1.UpdateOptions{})
|
||||
_, err = m.clientset.CoreV1().ConfigMaps(m.namespace).Update(ctx, cm, metav1.UpdateOptions{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update DHCP: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Manager) Set(ctx context.Context, key, value string) error {
|
||||
err := retry.RetryOnConflict(
|
||||
retry.DefaultRetry,
|
||||
func() error {
|
||||
p := []byte(fmt.Sprintf(`[{"op": "replace", "path": "/data/%s", "value": "%s"}]`, key, value))
|
||||
_, err := m.client.CoreV1().ConfigMaps(m.namespace).Patch(ctx, config.ConfigMapPodTrafficManager, types.JSONPatchType, p, metav1.PatchOptions{})
|
||||
return err
|
||||
})
|
||||
if err != nil {
|
||||
plog.G(ctx).Errorf("Failed to update configmap: %v", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Manager) Get(ctx context.Context, key string) (string, error) {
|
||||
cm, err := m.client.CoreV1().ConfigMaps(m.namespace).Get(ctx, config.ConfigMapPodTrafficManager, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return cm.Data[key], nil
|
||||
}
|
||||
|
||||
func (m *Manager) ForEach(ctx context.Context, fnv4 func(net.IP), fnv6 func(net.IP)) error {
|
||||
cm, err := m.client.CoreV1().ConfigMaps(m.namespace).Get(ctx, config.ConfigMapPodTrafficManager, metav1.GetOptions{})
|
||||
cm, err := m.clientset.CoreV1().ConfigMaps(m.namespace).Get(ctx, config.ConfigMapPodTrafficManager, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get cm DHCP server, err: %v", err)
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.6
|
||||
// protoc-gen-go v1.33.0
|
||||
// protoc v5.29.3
|
||||
// source: dhcpserver.proto
|
||||
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -22,18 +21,21 @@ const (
|
||||
)
|
||||
|
||||
type RentIPRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
PodName string `protobuf:"bytes,1,opt,name=PodName,proto3" json:"PodName,omitempty"`
|
||||
PodNamespace string `protobuf:"bytes,2,opt,name=PodNamespace,proto3" json:"PodNamespace,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
PodName string `protobuf:"bytes,1,opt,name=PodName,proto3" json:"PodName,omitempty"`
|
||||
PodNamespace string `protobuf:"bytes,2,opt,name=PodNamespace,proto3" json:"PodNamespace,omitempty"`
|
||||
}
|
||||
|
||||
func (x *RentIPRequest) Reset() {
|
||||
*x = RentIPRequest{}
|
||||
mi := &file_dhcpserver_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_dhcpserver_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *RentIPRequest) String() string {
|
||||
@@ -44,7 +46,7 @@ func (*RentIPRequest) ProtoMessage() {}
|
||||
|
||||
func (x *RentIPRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_dhcpserver_proto_msgTypes[0]
|
||||
if x != nil {
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -74,18 +76,21 @@ func (x *RentIPRequest) GetPodNamespace() string {
|
||||
}
|
||||
|
||||
type RentIPResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
IPv4CIDR string `protobuf:"bytes,1,opt,name=IPv4CIDR,proto3" json:"IPv4CIDR,omitempty"`
|
||||
IPv6CIDR string `protobuf:"bytes,2,opt,name=IPv6CIDR,proto3" json:"IPv6CIDR,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
IPv4CIDR string `protobuf:"bytes,1,opt,name=IPv4CIDR,proto3" json:"IPv4CIDR,omitempty"`
|
||||
IPv6CIDR string `protobuf:"bytes,2,opt,name=IPv6CIDR,proto3" json:"IPv6CIDR,omitempty"`
|
||||
}
|
||||
|
||||
func (x *RentIPResponse) Reset() {
|
||||
*x = RentIPResponse{}
|
||||
mi := &file_dhcpserver_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_dhcpserver_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *RentIPResponse) String() string {
|
||||
@@ -96,7 +101,7 @@ func (*RentIPResponse) ProtoMessage() {}
|
||||
|
||||
func (x *RentIPResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_dhcpserver_proto_msgTypes[1]
|
||||
if x != nil {
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -126,20 +131,23 @@ func (x *RentIPResponse) GetIPv6CIDR() string {
|
||||
}
|
||||
|
||||
type ReleaseIPRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
PodName string `protobuf:"bytes,1,opt,name=PodName,proto3" json:"PodName,omitempty"`
|
||||
PodNamespace string `protobuf:"bytes,2,opt,name=PodNamespace,proto3" json:"PodNamespace,omitempty"`
|
||||
IPv4CIDR string `protobuf:"bytes,3,opt,name=IPv4CIDR,proto3" json:"IPv4CIDR,omitempty"`
|
||||
IPv6CIDR string `protobuf:"bytes,4,opt,name=IPv6CIDR,proto3" json:"IPv6CIDR,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
PodName string `protobuf:"bytes,1,opt,name=PodName,proto3" json:"PodName,omitempty"`
|
||||
PodNamespace string `protobuf:"bytes,2,opt,name=PodNamespace,proto3" json:"PodNamespace,omitempty"`
|
||||
IPv4CIDR string `protobuf:"bytes,3,opt,name=IPv4CIDR,proto3" json:"IPv4CIDR,omitempty"`
|
||||
IPv6CIDR string `protobuf:"bytes,4,opt,name=IPv6CIDR,proto3" json:"IPv6CIDR,omitempty"`
|
||||
}
|
||||
|
||||
func (x *ReleaseIPRequest) Reset() {
|
||||
*x = ReleaseIPRequest{}
|
||||
mi := &file_dhcpserver_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_dhcpserver_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ReleaseIPRequest) String() string {
|
||||
@@ -150,7 +158,7 @@ func (*ReleaseIPRequest) ProtoMessage() {}
|
||||
|
||||
func (x *ReleaseIPRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_dhcpserver_proto_msgTypes[2]
|
||||
if x != nil {
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -194,17 +202,20 @@ func (x *ReleaseIPRequest) GetIPv6CIDR() string {
|
||||
}
|
||||
|
||||
type ReleaseIPResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"`
|
||||
}
|
||||
|
||||
func (x *ReleaseIPResponse) Reset() {
|
||||
*x = ReleaseIPResponse{}
|
||||
mi := &file_dhcpserver_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_dhcpserver_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ReleaseIPResponse) String() string {
|
||||
@@ -215,7 +226,7 @@ func (*ReleaseIPResponse) ProtoMessage() {}
|
||||
|
||||
func (x *ReleaseIPResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_dhcpserver_proto_msgTypes[3]
|
||||
if x != nil {
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -239,40 +250,55 @@ func (x *ReleaseIPResponse) GetMessage() string {
|
||||
|
||||
var File_dhcpserver_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_dhcpserver_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x10dhcpserver.proto\x12\x03rpc\"M\n" +
|
||||
"\rRentIPRequest\x12\x18\n" +
|
||||
"\aPodName\x18\x01 \x01(\tR\aPodName\x12\"\n" +
|
||||
"\fPodNamespace\x18\x02 \x01(\tR\fPodNamespace\"H\n" +
|
||||
"\x0eRentIPResponse\x12\x1a\n" +
|
||||
"\bIPv4CIDR\x18\x01 \x01(\tR\bIPv4CIDR\x12\x1a\n" +
|
||||
"\bIPv6CIDR\x18\x02 \x01(\tR\bIPv6CIDR\"\x88\x01\n" +
|
||||
"\x10ReleaseIPRequest\x12\x18\n" +
|
||||
"\aPodName\x18\x01 \x01(\tR\aPodName\x12\"\n" +
|
||||
"\fPodNamespace\x18\x02 \x01(\tR\fPodNamespace\x12\x1a\n" +
|
||||
"\bIPv4CIDR\x18\x03 \x01(\tR\bIPv4CIDR\x12\x1a\n" +
|
||||
"\bIPv6CIDR\x18\x04 \x01(\tR\bIPv6CIDR\"-\n" +
|
||||
"\x11ReleaseIPResponse\x12\x18\n" +
|
||||
"\amessage\x18\x01 \x01(\tR\amessage2y\n" +
|
||||
"\x04DHCP\x123\n" +
|
||||
"\x06RentIP\x12\x12.rpc.RentIPRequest\x1a\x13.rpc.RentIPResponse\"\x00\x12<\n" +
|
||||
"\tReleaseIP\x12\x15.rpc.ReleaseIPRequest\x1a\x16.rpc.ReleaseIPResponse\"\x00B\aZ\x05.;rpcb\x06proto3"
|
||||
var file_dhcpserver_proto_rawDesc = []byte{
|
||||
0x0a, 0x10, 0x64, 0x68, 0x63, 0x70, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x12, 0x03, 0x72, 0x70, 0x63, 0x22, 0x4d, 0x0a, 0x0d, 0x52, 0x65, 0x6e, 0x74, 0x49,
|
||||
0x50, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x50, 0x6f, 0x64, 0x4e,
|
||||
0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x50, 0x6f, 0x64, 0x4e, 0x61,
|
||||
0x6d, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x50, 0x6f, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61,
|
||||
0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x50, 0x6f, 0x64, 0x4e, 0x61, 0x6d,
|
||||
0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x48, 0x0a, 0x0e, 0x52, 0x65, 0x6e, 0x74, 0x49, 0x50,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x49, 0x50, 0x76, 0x34,
|
||||
0x43, 0x49, 0x44, 0x52, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x49, 0x50, 0x76, 0x34,
|
||||
0x43, 0x49, 0x44, 0x52, 0x12, 0x1a, 0x0a, 0x08, 0x49, 0x50, 0x76, 0x36, 0x43, 0x49, 0x44, 0x52,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x49, 0x50, 0x76, 0x36, 0x43, 0x49, 0x44, 0x52,
|
||||
0x22, 0x88, 0x01, 0x0a, 0x10, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x49, 0x50, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x50, 0x6f, 0x64, 0x4e, 0x61, 0x6d, 0x65,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x50, 0x6f, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x12,
|
||||
0x22, 0x0a, 0x0c, 0x50, 0x6f, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x50, 0x6f, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70,
|
||||
0x61, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x49, 0x50, 0x76, 0x34, 0x43, 0x49, 0x44, 0x52, 0x18,
|
||||
0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x49, 0x50, 0x76, 0x34, 0x43, 0x49, 0x44, 0x52, 0x12,
|
||||
0x1a, 0x0a, 0x08, 0x49, 0x50, 0x76, 0x36, 0x43, 0x49, 0x44, 0x52, 0x18, 0x04, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x08, 0x49, 0x50, 0x76, 0x36, 0x43, 0x49, 0x44, 0x52, 0x22, 0x2d, 0x0a, 0x11, 0x52,
|
||||
0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x49, 0x50, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x32, 0x79, 0x0a, 0x04, 0x44, 0x48,
|
||||
0x43, 0x50, 0x12, 0x33, 0x0a, 0x06, 0x52, 0x65, 0x6e, 0x74, 0x49, 0x50, 0x12, 0x12, 0x2e, 0x72,
|
||||
0x70, 0x63, 0x2e, 0x52, 0x65, 0x6e, 0x74, 0x49, 0x50, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x13, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x6e, 0x74, 0x49, 0x50, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3c, 0x0a, 0x09, 0x52, 0x65, 0x6c, 0x65, 0x61,
|
||||
0x73, 0x65, 0x49, 0x50, 0x12, 0x15, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x6c, 0x65, 0x61,
|
||||
0x73, 0x65, 0x49, 0x50, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x72, 0x70,
|
||||
0x63, 0x2e, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x49, 0x50, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x07, 0x5a, 0x05, 0x2e, 0x3b, 0x72, 0x70, 0x63, 0x62, 0x06,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_dhcpserver_proto_rawDescOnce sync.Once
|
||||
file_dhcpserver_proto_rawDescData []byte
|
||||
file_dhcpserver_proto_rawDescData = file_dhcpserver_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_dhcpserver_proto_rawDescGZIP() []byte {
|
||||
file_dhcpserver_proto_rawDescOnce.Do(func() {
|
||||
file_dhcpserver_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_dhcpserver_proto_rawDesc), len(file_dhcpserver_proto_rawDesc)))
|
||||
file_dhcpserver_proto_rawDescData = protoimpl.X.CompressGZIP(file_dhcpserver_proto_rawDescData)
|
||||
})
|
||||
return file_dhcpserver_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_dhcpserver_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
|
||||
var file_dhcpserver_proto_goTypes = []any{
|
||||
var file_dhcpserver_proto_goTypes = []interface{}{
|
||||
(*RentIPRequest)(nil), // 0: rpc.RentIPRequest
|
||||
(*RentIPResponse)(nil), // 1: rpc.RentIPResponse
|
||||
(*ReleaseIPRequest)(nil), // 2: rpc.ReleaseIPRequest
|
||||
@@ -295,11 +321,61 @@ func file_dhcpserver_proto_init() {
|
||||
if File_dhcpserver_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_dhcpserver_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*RentIPRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_dhcpserver_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*RentIPResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_dhcpserver_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ReleaseIPRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_dhcpserver_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ReleaseIPResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_dhcpserver_proto_rawDesc), len(file_dhcpserver_proto_rawDesc)),
|
||||
RawDescriptor: file_dhcpserver_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 4,
|
||||
NumExtensions: 0,
|
||||
@@ -310,6 +386,7 @@ func file_dhcpserver_proto_init() {
|
||||
MessageInfos: file_dhcpserver_proto_msgTypes,
|
||||
}.Build()
|
||||
File_dhcpserver_proto = out.File
|
||||
file_dhcpserver_proto_rawDesc = nil
|
||||
file_dhcpserver_proto_goTypes = nil
|
||||
file_dhcpserver_proto_depIdxs = nil
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.5.1
|
||||
// - protoc-gen-go-grpc v1.3.0
|
||||
// - protoc v5.29.3
|
||||
// source: dhcpserver.proto
|
||||
|
||||
@@ -15,8 +15,8 @@ import (
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
// Requires gRPC-Go v1.64.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion9
|
||||
// Requires gRPC-Go v1.32.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion7
|
||||
|
||||
const (
|
||||
DHCP_RentIP_FullMethodName = "/rpc.DHCP/RentIP"
|
||||
@@ -40,9 +40,8 @@ func NewDHCPClient(cc grpc.ClientConnInterface) DHCPClient {
|
||||
}
|
||||
|
||||
func (c *dHCPClient) RentIP(ctx context.Context, in *RentIPRequest, opts ...grpc.CallOption) (*RentIPResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(RentIPResponse)
|
||||
err := c.cc.Invoke(ctx, DHCP_RentIP_FullMethodName, in, out, cOpts...)
|
||||
err := c.cc.Invoke(ctx, DHCP_RentIP_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -50,9 +49,8 @@ func (c *dHCPClient) RentIP(ctx context.Context, in *RentIPRequest, opts ...grpc
|
||||
}
|
||||
|
||||
func (c *dHCPClient) ReleaseIP(ctx context.Context, in *ReleaseIPRequest, opts ...grpc.CallOption) (*ReleaseIPResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(ReleaseIPResponse)
|
||||
err := c.cc.Invoke(ctx, DHCP_ReleaseIP_FullMethodName, in, out, cOpts...)
|
||||
err := c.cc.Invoke(ctx, DHCP_ReleaseIP_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -61,19 +59,16 @@ func (c *dHCPClient) ReleaseIP(ctx context.Context, in *ReleaseIPRequest, opts .
|
||||
|
||||
// DHCPServer is the server API for DHCP service.
|
||||
// All implementations must embed UnimplementedDHCPServer
|
||||
// for forward compatibility.
|
||||
// for forward compatibility
|
||||
type DHCPServer interface {
|
||||
RentIP(context.Context, *RentIPRequest) (*RentIPResponse, error)
|
||||
ReleaseIP(context.Context, *ReleaseIPRequest) (*ReleaseIPResponse, error)
|
||||
mustEmbedUnimplementedDHCPServer()
|
||||
}
|
||||
|
||||
// UnimplementedDHCPServer must be embedded to have
|
||||
// forward compatible implementations.
|
||||
//
|
||||
// NOTE: this should be embedded by value instead of pointer to avoid a nil
|
||||
// pointer dereference when methods are called.
|
||||
type UnimplementedDHCPServer struct{}
|
||||
// UnimplementedDHCPServer must be embedded to have forward compatible implementations.
|
||||
type UnimplementedDHCPServer struct {
|
||||
}
|
||||
|
||||
func (UnimplementedDHCPServer) RentIP(context.Context, *RentIPRequest) (*RentIPResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method RentIP not implemented")
|
||||
@@ -82,7 +77,6 @@ func (UnimplementedDHCPServer) ReleaseIP(context.Context, *ReleaseIPRequest) (*R
|
||||
return nil, status.Errorf(codes.Unimplemented, "method ReleaseIP not implemented")
|
||||
}
|
||||
func (UnimplementedDHCPServer) mustEmbedUnimplementedDHCPServer() {}
|
||||
func (UnimplementedDHCPServer) testEmbeddedByValue() {}
|
||||
|
||||
// UnsafeDHCPServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to DHCPServer will
|
||||
@@ -92,13 +86,6 @@ type UnsafeDHCPServer interface {
|
||||
}
|
||||
|
||||
func RegisterDHCPServer(s grpc.ServiceRegistrar, srv DHCPServer) {
|
||||
// If the following call pancis, it indicates UnimplementedDHCPServer was
|
||||
// embedded by pointer and is nil. This will cause panics if an
|
||||
// unimplemented method is ever invoked, so we test this at initialization
|
||||
// time to prevent it from happening at runtime later due to I/O.
|
||||
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
|
||||
t.testEmbeddedByValue()
|
||||
}
|
||||
s.RegisterService(&DHCP_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
|
@@ -48,18 +48,19 @@ func (s *Server) ReleaseIP(ctx context.Context, req *rpc.ReleaseIPRequest) (*rpc
|
||||
defer s.Unlock()
|
||||
|
||||
plog.G(ctx).Infof("Handling release IP request, pod name: %s, ns: %s, IPv4: %s, IPv6: %s", req.PodName, req.PodNamespace, req.IPv4CIDR, req.IPv6CIDR)
|
||||
var ips []net.IP
|
||||
for _, ipStr := range []string{req.IPv4CIDR, req.IPv6CIDR} {
|
||||
ip, _, err := net.ParseCIDR(ipStr)
|
||||
if err != nil {
|
||||
plog.G(ctx).Errorf("IP %s is invailed: %v", ipStr, err)
|
||||
continue
|
||||
}
|
||||
ips = append(ips, ip)
|
||||
|
||||
ipv4, _, err := net.ParseCIDR(req.IPv4CIDR)
|
||||
if err != nil {
|
||||
plog.G(ctx).Errorf("IP %s is invailed: %v", req.IPv4CIDR, err)
|
||||
}
|
||||
var ipv6 net.IP
|
||||
ipv6, _, err = net.ParseCIDR(req.IPv6CIDR)
|
||||
if err != nil {
|
||||
plog.G(ctx).Errorf("IP %s is invailed: %v", req.IPv6CIDR, err)
|
||||
}
|
||||
|
||||
manager := NewDHCPManager(s.clientset, req.PodNamespace)
|
||||
if err := manager.ReleaseIP(ctx, ips...); err != nil {
|
||||
if err = manager.ReleaseIP(ctx, ipv4, ipv6); err != nil {
|
||||
plog.G(ctx).Errorf("Failed to release IP: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
|
@@ -8,7 +8,7 @@ import (
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/utils/pointer"
|
||||
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/config"
|
||||
@@ -25,62 +25,72 @@ func (c *ConnectOptions) setupSignalHandler() {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ConnectOptions) Cleanup(ctx context.Context) {
|
||||
func (c *ConnectOptions) Cleanup(logCtx context.Context) {
|
||||
if c == nil {
|
||||
return
|
||||
}
|
||||
|
||||
var inUserDaemon bool
|
||||
// only root daemon really do connect
|
||||
// root daemon: data plane
|
||||
// user daemon: control plane
|
||||
var userDaemon = true
|
||||
if c.ctx != nil {
|
||||
inUserDaemon = true
|
||||
userDaemon = false
|
||||
}
|
||||
|
||||
c.once.Do(func() {
|
||||
if inUserDaemon {
|
||||
plog.G(ctx).Info("Performing cleanup operations")
|
||||
}
|
||||
ctx2, cancel := context.WithTimeout(context.Background(), time.Second*10)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
|
||||
defer cancel()
|
||||
var ips []net.IP
|
||||
if c.localTunIPv4 != nil && c.localTunIPv4.IP != nil {
|
||||
ips = append(ips, c.localTunIPv4.IP)
|
||||
}
|
||||
if c.localTunIPv6 != nil && c.localTunIPv6.IP != nil {
|
||||
ips = append(ips, c.localTunIPv6.IP)
|
||||
}
|
||||
if c.dhcp != nil {
|
||||
err := c.dhcp.ReleaseIP(ctx2, ips...)
|
||||
if err != nil {
|
||||
plog.G(ctx).Errorf("Failed to release IP to DHCP server: %v", err)
|
||||
} else {
|
||||
plog.G(ctx).Infof("Releaseed IP %v to DHCP server", ips)
|
||||
if userDaemon {
|
||||
plog.G(logCtx).Info("Performing cleanup operations")
|
||||
var ipv4, ipv6 net.IP
|
||||
if c.LocalTunIPv4 != nil && c.LocalTunIPv4.IP != nil {
|
||||
ipv4 = c.LocalTunIPv4.IP
|
||||
}
|
||||
}
|
||||
if c.clientset != nil {
|
||||
_ = c.clientset.CoreV1().Pods(c.Namespace).Delete(ctx2, config.CniNetName, v1.DeleteOptions{GracePeriodSeconds: pointer.Int64(0)})
|
||||
_ = c.clientset.BatchV1().Jobs(c.Namespace).Delete(ctx2, config.ConfigMapPodTrafficManager, v1.DeleteOptions{GracePeriodSeconds: pointer.Int64(0)})
|
||||
}
|
||||
// leave proxy resources
|
||||
err := c.LeaveAllProxyResources(ctx2)
|
||||
if err != nil {
|
||||
plog.G(ctx).Errorf("Leave proxy resources error: %v", err)
|
||||
}
|
||||
if c.cancel != nil {
|
||||
c.cancel()
|
||||
}
|
||||
|
||||
for _, function := range c.getRolloutFunc() {
|
||||
if function != nil {
|
||||
if err = function(); err != nil {
|
||||
plog.G(ctx).Warnf("Rollout function error: %v", err)
|
||||
if c.LocalTunIPv6 != nil && c.LocalTunIPv6.IP != nil {
|
||||
ipv6 = c.LocalTunIPv6.IP
|
||||
}
|
||||
if c.dhcp != nil {
|
||||
err := c.dhcp.ReleaseIP(ctx, ipv4, ipv6)
|
||||
if err != nil {
|
||||
plog.G(logCtx).Errorf("Failed to release IP to DHCP server: %v", err)
|
||||
} else {
|
||||
plog.G(logCtx).Infof("Releaseed IPv4 %v IPv6 %v to DHCP server", ipv4, ipv6)
|
||||
}
|
||||
}
|
||||
}
|
||||
if c.dnsConfig != nil {
|
||||
if inUserDaemon {
|
||||
plog.G(ctx2).Infof("Clearing DNS settings")
|
||||
if c.clientset != nil {
|
||||
_ = c.clientset.CoreV1().Pods(c.Namespace).Delete(ctx, config.CniNetName, v1.DeleteOptions{GracePeriodSeconds: pointer.Int64(0)})
|
||||
_ = c.clientset.BatchV1().Jobs(c.Namespace).Delete(ctx, config.ConfigMapPodTrafficManager, v1.DeleteOptions{GracePeriodSeconds: pointer.Int64(0)})
|
||||
}
|
||||
// leave proxy resources
|
||||
err := c.LeaveAllProxyResources(ctx)
|
||||
if err != nil {
|
||||
plog.G(logCtx).Errorf("Leave proxy resources error: %v", err)
|
||||
}
|
||||
|
||||
for _, function := range c.getRolloutFunc() {
|
||||
if function != nil {
|
||||
if err = function(); err != nil {
|
||||
plog.G(logCtx).Warnf("Rollout function error: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if c.cancel != nil {
|
||||
c.cancel()
|
||||
}
|
||||
|
||||
for _, function := range c.getRolloutFunc() {
|
||||
if function != nil {
|
||||
if err := function(); err != nil {
|
||||
plog.G(logCtx).Warnf("Rollout function error: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
if c.dnsConfig != nil {
|
||||
plog.G(logCtx).Infof("Clearing DNS settings")
|
||||
c.dnsConfig.CancelDNS()
|
||||
}
|
||||
c.dnsConfig.CancelDNS()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@@ -32,6 +32,7 @@ import (
|
||||
"k8s.io/utils/ptr"
|
||||
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/config"
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/daemon/rpc"
|
||||
plog "github.com/wencaiwulue/kubevpn/v2/pkg/log"
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/syncthing"
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/util"
|
||||
@@ -51,6 +52,7 @@ type CloneOptions struct {
|
||||
OriginKubeconfigPath string
|
||||
LocalDir string
|
||||
RemoteDir string
|
||||
Request *rpc.CloneRequest `json:"Request,omitempty"`
|
||||
|
||||
clientset *kubernetes.Clientset
|
||||
restclient *rest.RESTClient
|
||||
|
@@ -5,7 +5,6 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net"
|
||||
"reflect"
|
||||
"slices"
|
||||
"sort"
|
||||
"strconv"
|
||||
@@ -30,6 +29,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
pkgruntime "k8s.io/apimachinery/pkg/runtime"
|
||||
k8stypes "k8s.io/apimachinery/pkg/types"
|
||||
pkgtypes "k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
@@ -52,6 +52,7 @@ import (
|
||||
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/config"
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/core"
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/daemon/rpc"
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/dhcp"
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/dns"
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/driver"
|
||||
@@ -71,6 +72,7 @@ type ConnectOptions struct {
|
||||
Lock *sync.Mutex
|
||||
Image string
|
||||
ImagePullSecretName string
|
||||
Request *rpc.ConnectRequest `json:"Request,omitempty"`
|
||||
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
@@ -82,8 +84,8 @@ type ConnectOptions struct {
|
||||
cidrs []*net.IPNet
|
||||
dhcp *dhcp.Manager
|
||||
// needs to give it back to dhcp
|
||||
localTunIPv4 *net.IPNet
|
||||
localTunIPv6 *net.IPNet
|
||||
LocalTunIPv4 *net.IPNet `json:"LocalTunIPv4,omitempty"`
|
||||
LocalTunIPv6 *net.IPNet `json:"LocalTunIPv6,omitempty"`
|
||||
rollbackFuncList []func() error
|
||||
dnsConfig *dns.Config
|
||||
|
||||
@@ -106,21 +108,28 @@ func (c *ConnectOptions) InitDHCP(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *ConnectOptions) RentIP(ctx context.Context) (context.Context, error) {
|
||||
func (c *ConnectOptions) RentIP(ctx context.Context, ipv4, ipv6 string) (context.Context, error) {
|
||||
if err := c.InitDHCP(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var err error
|
||||
c.localTunIPv4, c.localTunIPv6, err = c.dhcp.RentIP(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if util.IsValidCIDR(ipv4) && util.IsValidCIDR(ipv6) {
|
||||
ip, cidr, _ := net.ParseCIDR(ipv4)
|
||||
c.LocalTunIPv4 = &net.IPNet{IP: ip, Mask: cidr.Mask}
|
||||
ip, cidr, _ = net.ParseCIDR(ipv6)
|
||||
c.LocalTunIPv6 = &net.IPNet{IP: ip, Mask: cidr.Mask}
|
||||
} else {
|
||||
var err error
|
||||
c.LocalTunIPv4, c.LocalTunIPv6, err = c.dhcp.RentIP(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
ctx1 := metadata.AppendToOutgoingContext(
|
||||
|
||||
return metadata.AppendToOutgoingContext(
|
||||
context.Background(),
|
||||
config.HeaderIPv4, c.localTunIPv4.String(),
|
||||
config.HeaderIPv6, c.localTunIPv6.String(),
|
||||
)
|
||||
return ctx1, nil
|
||||
config.HeaderIPv4, c.LocalTunIPv4.String(),
|
||||
config.HeaderIPv6, c.LocalTunIPv6.String(),
|
||||
), nil
|
||||
}
|
||||
|
||||
func (c *ConnectOptions) GetIPFromContext(ctx context.Context, logger *log.Logger) error {
|
||||
@@ -137,8 +146,8 @@ func (c *ConnectOptions) GetIPFromContext(ctx context.Context, logger *log.Logge
|
||||
if err != nil {
|
||||
return fmt.Errorf("cat not convert IPv4 string: %s: %v", ipv4[0], err)
|
||||
}
|
||||
c.localTunIPv4 = &net.IPNet{IP: ip, Mask: ipNet.Mask}
|
||||
logger.Debugf("Get IPv4 %s from context", c.localTunIPv4.String())
|
||||
c.LocalTunIPv4 = &net.IPNet{IP: ip, Mask: ipNet.Mask}
|
||||
logger.Debugf("Get IPv4 %s from context", c.LocalTunIPv4.String())
|
||||
|
||||
ipv6 := md.Get(config.HeaderIPv6)
|
||||
if len(ipv6) == 0 {
|
||||
@@ -148,13 +157,13 @@ func (c *ConnectOptions) GetIPFromContext(ctx context.Context, logger *log.Logge
|
||||
if err != nil {
|
||||
return fmt.Errorf("cat not convert IPv6 string: %s: %v", ipv6[0], err)
|
||||
}
|
||||
c.localTunIPv6 = &net.IPNet{IP: ip, Mask: ipNet.Mask}
|
||||
logger.Debugf("Get IPv6 %s from context", c.localTunIPv6.String())
|
||||
c.LocalTunIPv6 = &net.IPNet{IP: ip, Mask: ipNet.Mask}
|
||||
logger.Debugf("Get IPv6 %s from context", c.LocalTunIPv6.String())
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *ConnectOptions) CreateRemoteInboundPod(ctx context.Context, namespace string, workloads []string, headers map[string]string, portMap []string, image string) (err error) {
|
||||
if c.localTunIPv4 == nil || c.localTunIPv6 == nil {
|
||||
if c.LocalTunIPv4 == nil || c.LocalTunIPv6 == nil {
|
||||
return fmt.Errorf("local tun IP is invalid")
|
||||
}
|
||||
if c.proxyWorkloads == nil {
|
||||
@@ -169,8 +178,8 @@ func (c *ConnectOptions) CreateRemoteInboundPod(ctx context.Context, namespace s
|
||||
for _, workload := range workloads {
|
||||
plog.G(ctx).Infof("Injecting inbound sidecar for %s in namespace %s", workload, namespace)
|
||||
configInfo := util.PodRouteConfig{
|
||||
LocalTunIPv4: c.localTunIPv4.IP.String(),
|
||||
LocalTunIPv6: c.localTunIPv6.IP.String(),
|
||||
LocalTunIPv4: c.LocalTunIPv4.IP.String(),
|
||||
LocalTunIPv6: c.LocalTunIPv6.IP.String(),
|
||||
}
|
||||
var object, controller *runtimeresource.Info
|
||||
object, controller, err = util.GetTopOwnerObject(ctx, c.factory, namespace, workload)
|
||||
@@ -211,13 +220,12 @@ func (c *ConnectOptions) CreateRemoteInboundPod(ctx context.Context, namespace s
|
||||
func (c *ConnectOptions) DoConnect(ctx context.Context, isLite bool) (err error) {
|
||||
c.ctx, c.cancel = context.WithCancel(ctx)
|
||||
plog.G(ctx).Info("Starting connect to cluster")
|
||||
m := dhcp.NewDHCPManager(c.clientset, c.Namespace)
|
||||
if err = m.InitDHCP(c.ctx); err != nil {
|
||||
if err = c.InitDHCP(c.ctx); err != nil {
|
||||
plog.G(ctx).Errorf("Init DHCP server failed: %v", err)
|
||||
return
|
||||
}
|
||||
go c.setupSignalHandler()
|
||||
if err = c.getCIDR(c.ctx, m); err != nil {
|
||||
if err = c.getCIDR(c.ctx); err != nil {
|
||||
plog.G(ctx).Errorf("Failed to get network CIDR: %v", err)
|
||||
return
|
||||
}
|
||||
@@ -324,7 +332,7 @@ func (c *ConnectOptions) portForward(ctx context.Context, portPair []string) err
|
||||
// try to detect pod is delete event, if pod is deleted, needs to redo port-forward
|
||||
go util.CheckPodStatus(childCtx, cancelFunc, podName, c.clientset.CoreV1().Pods(c.Namespace))
|
||||
domain := fmt.Sprintf("%s.%s", config.ConfigMapPodTrafficManager, c.Namespace)
|
||||
go healthCheckPortForward(childCtx, cancelFunc, readyChan, strings.Split(portPair[1], ":")[0], domain, c.localTunIPv4.IP)
|
||||
go healthCheckPortForward(childCtx, cancelFunc, readyChan, strings.Split(portPair[1], ":")[0], domain, c.LocalTunIPv4.IP)
|
||||
go healthCheckTCPConn(childCtx, cancelFunc, readyChan, domain, util.GetPodIP(pod)[0])
|
||||
if *first {
|
||||
go func() {
|
||||
@@ -380,7 +388,7 @@ func (c *ConnectOptions) portForward(ctx context.Context, portPair []string) err
|
||||
}
|
||||
|
||||
func (c *ConnectOptions) startLocalTunServer(ctx context.Context, forwardAddress string, lite bool) (err error) {
|
||||
plog.G(ctx).Debugf("IPv4: %s, IPv6: %s", c.localTunIPv4.IP.String(), c.localTunIPv6.IP.String())
|
||||
plog.G(ctx).Debugf("IPv4: %s, IPv6: %s", c.LocalTunIPv4.IP.String(), c.LocalTunIPv6.IP.String())
|
||||
|
||||
tlsSecret, err := c.clientset.CoreV1().Secrets(c.Namespace).Get(ctx, config.ConfigMapPodTrafficManager, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
@@ -394,8 +402,8 @@ func (c *ConnectOptions) startLocalTunServer(ctx context.Context, forwardAddress
|
||||
// windows needs to add tun IP self to route table, but linux and macOS not need
|
||||
if util.IsWindows() {
|
||||
cidrList = append(cidrList,
|
||||
&net.IPNet{IP: c.localTunIPv4.IP, Mask: net.CIDRMask(32, 32)},
|
||||
&net.IPNet{IP: c.localTunIPv6.IP, Mask: net.CIDRMask(128, 128)},
|
||||
&net.IPNet{IP: c.LocalTunIPv4.IP, Mask: net.CIDRMask(32, 32)},
|
||||
&net.IPNet{IP: c.LocalTunIPv6.IP, Mask: net.CIDRMask(128, 128)},
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -420,12 +428,12 @@ func (c *ConnectOptions) startLocalTunServer(ctx context.Context, forwardAddress
|
||||
}
|
||||
|
||||
tunConfig := tun.Config{
|
||||
Addr: (&net.IPNet{IP: c.localTunIPv4.IP, Mask: net.CIDRMask(32, 32)}).String(),
|
||||
Addr: (&net.IPNet{IP: c.LocalTunIPv4.IP, Mask: net.CIDRMask(32, 32)}).String(),
|
||||
Routes: routes,
|
||||
MTU: config.DefaultMTU,
|
||||
}
|
||||
if enable, _ := util.IsIPv6Enabled(); enable {
|
||||
tunConfig.Addr6 = (&net.IPNet{IP: c.localTunIPv6.IP, Mask: net.CIDRMask(128, 128)}).String()
|
||||
tunConfig.Addr6 = (&net.IPNet{IP: c.LocalTunIPv6.IP, Mask: net.CIDRMask(128, 128)}).String()
|
||||
}
|
||||
|
||||
localNode := fmt.Sprintf("tun:/127.0.0.1:8422")
|
||||
@@ -814,7 +822,7 @@ func (c *ConnectOptions) GetRunningPodList(ctx context.Context) ([]v1.Pod, error
|
||||
// https://stackoverflow.com/questions/45903123/kubernetes-set-service-cidr-and-pod-cidr-the-same
|
||||
// https://stackoverflow.com/questions/44190607/how-do-you-find-the-cluster-service-cidr-of-a-kubernetes-cluster/54183373#54183373
|
||||
// https://stackoverflow.com/questions/44190607/how-do-you-find-the-cluster-service-cidr-of-a-kubernetes-cluster
|
||||
func (c *ConnectOptions) getCIDR(ctx context.Context, m *dhcp.Manager) error {
|
||||
func (c *ConnectOptions) getCIDR(ctx context.Context) error {
|
||||
var err error
|
||||
c.apiServerIPs, err = util.GetAPIServerIP(c.config.Host)
|
||||
if err != nil {
|
||||
@@ -823,7 +831,7 @@ func (c *ConnectOptions) getCIDR(ctx context.Context, m *dhcp.Manager) error {
|
||||
|
||||
// (1) get CIDR from cache
|
||||
var ipPoolStr string
|
||||
ipPoolStr, err = m.Get(ctx, config.KeyClusterIPv4POOLS)
|
||||
ipPoolStr, err = c.Get(ctx, config.KeyClusterIPv4POOLS)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -845,7 +853,30 @@ func (c *ConnectOptions) getCIDR(ctx context.Context, m *dhcp.Manager) error {
|
||||
for _, cidr := range c.cidrs {
|
||||
s.Insert(cidr.String())
|
||||
}
|
||||
return m.Set(ctx, config.KeyClusterIPv4POOLS, strings.Join(s.UnsortedList(), " "))
|
||||
return c.Set(ctx, config.KeyClusterIPv4POOLS, strings.Join(s.UnsortedList(), " "))
|
||||
}
|
||||
|
||||
func (c *ConnectOptions) Set(ctx context.Context, key, value string) error {
|
||||
err := retry.RetryOnConflict(
|
||||
retry.DefaultRetry,
|
||||
func() error {
|
||||
p := []byte(fmt.Sprintf(`[{"op": "replace", "path": "/data/%s", "value": "%s"}]`, key, value))
|
||||
_, err := c.clientset.CoreV1().ConfigMaps(c.Namespace).Patch(ctx, config.ConfigMapPodTrafficManager, k8stypes.JSONPatchType, p, metav1.PatchOptions{})
|
||||
return err
|
||||
})
|
||||
if err != nil {
|
||||
plog.G(ctx).Errorf("Failed to update configmap: %v", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *ConnectOptions) Get(ctx context.Context, key string) (string, error) {
|
||||
cm, err := c.clientset.CoreV1().ConfigMaps(c.Namespace).Get(ctx, config.ConfigMapPodTrafficManager, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return cm.Data[key], nil
|
||||
}
|
||||
|
||||
func (c *ConnectOptions) addExtraRoute(ctx context.Context, name string) error {
|
||||
@@ -959,11 +990,11 @@ func (c *ConnectOptions) GetFactory() cmdutil.Factory {
|
||||
}
|
||||
|
||||
func (c *ConnectOptions) GetLocalTunIP() (v4 string, v6 string) {
|
||||
if c.localTunIPv4 != nil {
|
||||
v4 = c.localTunIPv4.IP.String()
|
||||
if c.LocalTunIPv4 != nil {
|
||||
v4 = c.LocalTunIPv4.IP.String()
|
||||
}
|
||||
if c.localTunIPv6 != nil {
|
||||
v6 = c.localTunIPv6.IP.String()
|
||||
if c.LocalTunIPv6 != nil {
|
||||
v6 = c.LocalTunIPv6.IP.String()
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -1211,20 +1242,13 @@ func deletePodImmediately(ctx context.Context, clientset *kubernetes.Clientset,
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *ConnectOptions) Equal(a *ConnectOptions) bool {
|
||||
return c.Engine == a.Engine &&
|
||||
sets.New[string](c.ExtraRouteInfo.ExtraDomain...).HasAll(a.ExtraRouteInfo.ExtraDomain...) &&
|
||||
sets.New[string](c.ExtraRouteInfo.ExtraCIDR...).HasAll(c.ExtraRouteInfo.ExtraCIDR...) &&
|
||||
(reflect.DeepEqual(c.ExtraRouteInfo.ExtraNodeIP, a.ExtraRouteInfo.ExtraNodeIP) || c.ExtraRouteInfo.ExtraNodeIP == true)
|
||||
}
|
||||
|
||||
func (c *ConnectOptions) GetTunDeviceName() (string, error) {
|
||||
var ips []net.IP
|
||||
if c.localTunIPv4 != nil {
|
||||
ips = append(ips, c.localTunIPv4.IP)
|
||||
if c.LocalTunIPv4 != nil {
|
||||
ips = append(ips, c.LocalTunIPv4.IP)
|
||||
}
|
||||
if c.localTunIPv6 != nil {
|
||||
ips = append(ips, c.localTunIPv6.IP)
|
||||
if c.LocalTunIPv6 != nil {
|
||||
ips = append(ips, c.LocalTunIPv6.IP)
|
||||
}
|
||||
device, err := util.GetTunDevice(ips...)
|
||||
if err != nil {
|
||||
|
@@ -47,8 +47,8 @@ func (l *ProxyList) Remove(ns, workload string) {
|
||||
}
|
||||
}
|
||||
|
||||
func (l *ProxyList) Add(connectNamespace string, proxy *Proxy) {
|
||||
go proxy.portMapper.Run(connectNamespace)
|
||||
func (l *ProxyList) Add(managerNamespace string, proxy *Proxy) {
|
||||
go proxy.portMapper.Run(managerNamespace)
|
||||
*l = append(*l, proxy)
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ type Mapper struct {
|
||||
clientset *kubernetes.Clientset
|
||||
}
|
||||
|
||||
func (m *Mapper) Run(connectNamespace string) {
|
||||
func (m *Mapper) Run(managerNamespace string) {
|
||||
if m == nil {
|
||||
return
|
||||
}
|
||||
@@ -121,7 +121,7 @@ func (m *Mapper) Run(connectNamespace string) {
|
||||
|
||||
var lastLocalPort2EnvoyRulePort map[int32]int32
|
||||
for m.ctx.Err() == nil {
|
||||
localPort2EnvoyRulePort, err := m.getLocalPort2EnvoyRulePort(connectNamespace)
|
||||
localPort2EnvoyRulePort, err := m.getLocalPort2EnvoyRulePort(managerNamespace)
|
||||
if err != nil {
|
||||
if errors.Is(err, context.Canceled) {
|
||||
continue
|
||||
@@ -200,8 +200,8 @@ func (m *Mapper) Run(connectNamespace string) {
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Mapper) getLocalPort2EnvoyRulePort(connectNamespace string) (map[int32]int32, error) {
|
||||
configMap, err := m.clientset.CoreV1().ConfigMaps(connectNamespace).Get(m.ctx, config.ConfigMapPodTrafficManager, v1.GetOptions{})
|
||||
func (m *Mapper) getLocalPort2EnvoyRulePort(managerNamespace string) (map[int32]int32, error) {
|
||||
configMap, err := m.clientset.CoreV1().ConfigMaps(managerNamespace).Get(m.ctx, config.ConfigMapPodTrafficManager, v1.GetOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@@ -77,7 +77,7 @@ func resetConfigMap(ctx context.Context, mapInterface v1.ConfigMapInterface, nam
|
||||
}
|
||||
|
||||
for i := 0; i < len(v); i++ {
|
||||
if ws.Has(v[i].Uid) {
|
||||
if ws.Has(v[i].Uid) && v[i].Namespace == namespace {
|
||||
v = append(v[:i], v[i+1:]...)
|
||||
i--
|
||||
}
|
||||
|
@@ -38,7 +38,7 @@ func RemoveContainers(spec *v1.PodTemplateSpec) {
|
||||
}
|
||||
|
||||
// AddMeshContainer todo envoy support ipv6
|
||||
func AddMeshContainer(spec *v1.PodTemplateSpec, ns, nodeID string, ipv6 bool, connectNamespace string, secret *v1.Secret, image string) {
|
||||
func AddMeshContainer(spec *v1.PodTemplateSpec, ns, nodeID string, ipv6 bool, managerNamespace string, secret *v1.Secret, image string) {
|
||||
// remove envoy proxy containers if already exist
|
||||
RemoveContainers(spec)
|
||||
|
||||
@@ -80,7 +80,7 @@ kubevpn server -l "tun:/localhost:8422?net=${TunIPv4}&net6=${TunIPv6}&route=${CI
|
||||
},
|
||||
{
|
||||
Name: "TrafficManagerService",
|
||||
Value: fmt.Sprintf("%s.%s", config.ConfigMapPodTrafficManager, connectNamespace),
|
||||
Value: fmt.Sprintf("%s.%s", config.ConfigMapPodTrafficManager, managerNamespace),
|
||||
},
|
||||
{
|
||||
Name: config.EnvPodNamespace,
|
||||
@@ -152,9 +152,9 @@ kubevpn server -l "tun:/localhost:8422?net=${TunIPv4}&net6=${TunIPv6}&route=${CI
|
||||
Args: []string{
|
||||
func() string {
|
||||
if ipv6 {
|
||||
return GetEnvoyConfig(string(envoyConfig), fmt.Sprintf("%s.%s", config.ConfigMapPodTrafficManager, connectNamespace))
|
||||
return GetEnvoyConfig(string(envoyConfig), fmt.Sprintf("%s.%s", config.ConfigMapPodTrafficManager, managerNamespace))
|
||||
}
|
||||
return GetEnvoyConfig(string(envoyConfigIPv4), fmt.Sprintf("%s.%s", config.ConfigMapPodTrafficManager, connectNamespace))
|
||||
return GetEnvoyConfig(string(envoyConfigIPv4), fmt.Sprintf("%s.%s", config.ConfigMapPodTrafficManager, managerNamespace))
|
||||
}(),
|
||||
},
|
||||
Resources: v1.ResourceRequirements{
|
||||
@@ -171,7 +171,7 @@ kubevpn server -l "tun:/localhost:8422?net=${TunIPv4}&net6=${TunIPv6}&route=${CI
|
||||
})
|
||||
}
|
||||
|
||||
func AddEnvoyContainer(spec *v1.PodTemplateSpec, ns, nodeID string, ipv6 bool, connectNamespace string, image string) {
|
||||
func AddEnvoyContainer(spec *v1.PodTemplateSpec, ns, nodeID string, ipv6 bool, managerNamespace string, image string) {
|
||||
// remove envoy proxy containers if already exist
|
||||
RemoveContainers(spec)
|
||||
|
||||
@@ -216,9 +216,9 @@ kubevpn server -l "ssh://:2222"`,
|
||||
Args: []string{
|
||||
func() string {
|
||||
if ipv6 {
|
||||
return GetEnvoyConfig(string(envoyConfigFargate), fmt.Sprintf("%s.%s", config.ConfigMapPodTrafficManager, connectNamespace))
|
||||
return GetEnvoyConfig(string(envoyConfigFargate), fmt.Sprintf("%s.%s", config.ConfigMapPodTrafficManager, managerNamespace))
|
||||
}
|
||||
return GetEnvoyConfig(string(envoyConfigIPv4Fargate), fmt.Sprintf("%s.%s", config.ConfigMapPodTrafficManager, connectNamespace))
|
||||
return GetEnvoyConfig(string(envoyConfigIPv4Fargate), fmt.Sprintf("%s.%s", config.ConfigMapPodTrafficManager, managerNamespace))
|
||||
}(),
|
||||
},
|
||||
Resources: v1.ResourceRequirements{
|
||||
|
@@ -20,7 +20,7 @@ func RemoveContainer(spec *corev1.PodSpec) {
|
||||
}
|
||||
}
|
||||
|
||||
func AddContainer(spec *corev1.PodSpec, c util.PodRouteConfig, connectNamespace string, secret *corev1.Secret, image string) {
|
||||
func AddContainer(spec *corev1.PodSpec, c util.PodRouteConfig, managerNamespace string, secret *corev1.Secret, image string) {
|
||||
// remove vpn container if already exist
|
||||
RemoveContainer(spec)
|
||||
spec.Containers = append(spec.Containers, corev1.Container{
|
||||
@@ -53,7 +53,7 @@ func AddContainer(spec *corev1.PodSpec, c util.PodRouteConfig, connectNamespace
|
||||
},
|
||||
{
|
||||
Name: "TrafficManagerService",
|
||||
Value: fmt.Sprintf("%s.%s", config.ConfigMapPodTrafficManager, connectNamespace),
|
||||
Value: fmt.Sprintf("%s.%s", config.ConfigMapPodTrafficManager, managerNamespace),
|
||||
},
|
||||
{
|
||||
Name: config.EnvPodNamespace,
|
||||
|
@@ -27,7 +27,7 @@ import (
|
||||
|
||||
// InjectEnvoySidecar patch a sidecar, using iptables to do port-forward let this pod decide should go to 233.254.254.100 or request to 127.0.0.1
|
||||
// https://istio.io/latest/docs/ops/deployment/requirements/#ports-used-by-istio
|
||||
func InjectEnvoySidecar(ctx context.Context, nodeID string, f cmdutil.Factory, connectNamespace string, current, object *runtimeresource.Info, headers map[string]string, portMap []string, image string) (err error) {
|
||||
func InjectEnvoySidecar(ctx context.Context, nodeID string, f cmdutil.Factory, managerNamespace string, current, object *runtimeresource.Info, headers map[string]string, portMap []string, image string) (err error) {
|
||||
var clientset *kubernetes.Clientset
|
||||
clientset, err = f.KubernetesClientSet()
|
||||
if err != nil {
|
||||
@@ -50,7 +50,7 @@ func InjectEnvoySidecar(ctx context.Context, nodeID string, f cmdutil.Factory, c
|
||||
port[i].EnvoyListenerPort = int32(randomPort)
|
||||
containerPort2EnvoyListenerPort[port[i].ContainerPort] = int32(randomPort)
|
||||
}
|
||||
err = addEnvoyConfig(clientset.CoreV1().ConfigMaps(connectNamespace), object.Namespace, nodeID, c, headers, port, portmap)
|
||||
err = addEnvoyConfig(clientset.CoreV1().ConfigMaps(managerNamespace), object.Namespace, nodeID, c, headers, port, portmap)
|
||||
if err != nil {
|
||||
plog.G(ctx).Errorf("Failed to add envoy config: %v", err)
|
||||
return err
|
||||
@@ -66,9 +66,9 @@ func InjectEnvoySidecar(ctx context.Context, nodeID string, f cmdutil.Factory, c
|
||||
return
|
||||
}
|
||||
|
||||
enableIPv6, _ := util.DetectPodSupportIPv6(ctx, f, connectNamespace)
|
||||
enableIPv6, _ := util.DetectPodSupportIPv6(ctx, f, managerNamespace)
|
||||
// (1) add mesh container
|
||||
AddEnvoyContainer(templateSpec, object.Namespace, nodeID, enableIPv6, connectNamespace, image)
|
||||
AddEnvoyContainer(templateSpec, object.Namespace, nodeID, enableIPv6, managerNamespace, image)
|
||||
helper := pkgresource.NewHelper(object.Client, object.Mapping)
|
||||
ps := []P{
|
||||
{
|
||||
|
@@ -32,7 +32,7 @@ import (
|
||||
// https://istio.io/latest/docs/ops/deployment/requirements/#ports-used-by-istio
|
||||
|
||||
// InjectVPNAndEnvoySidecar patch a sidecar, using iptables to do port-forward let this pod decide should go to 233.254.254.100 or request to 127.0.0.1
|
||||
func InjectVPNAndEnvoySidecar(ctx context.Context, nodeID string, f cmdutil.Factory, connectNamespace string, object *runtimeresource.Info, c util.PodRouteConfig, headers map[string]string, portMaps []string, secret *v1.Secret, image string) (err error) {
|
||||
func InjectVPNAndEnvoySidecar(ctx context.Context, nodeID string, f cmdutil.Factory, managerNamespace string, object *runtimeresource.Info, c util.PodRouteConfig, headers map[string]string, portMaps []string, secret *v1.Secret, image string) (err error) {
|
||||
var clientset *kubernetes.Clientset
|
||||
clientset, err = f.KubernetesClientSet()
|
||||
if err != nil {
|
||||
@@ -77,7 +77,7 @@ func InjectVPNAndEnvoySidecar(ctx context.Context, nodeID string, f cmdutil.Fact
|
||||
}
|
||||
}
|
||||
|
||||
err = addEnvoyConfig(clientset.CoreV1().ConfigMaps(connectNamespace), object.Namespace, nodeID, c, headers, ports, portmap)
|
||||
err = addEnvoyConfig(clientset.CoreV1().ConfigMaps(managerNamespace), object.Namespace, nodeID, c, headers, ports, portmap)
|
||||
if err != nil {
|
||||
plog.G(ctx).Errorf("Failed to add envoy config: %v", err)
|
||||
return err
|
||||
@@ -89,13 +89,13 @@ func InjectVPNAndEnvoySidecar(ctx context.Context, nodeID string, f cmdutil.Fact
|
||||
containerNames.Insert(container.Name)
|
||||
}
|
||||
if containerNames.HasAll(config.ContainerSidecarVPN, config.ContainerSidecarEnvoyProxy) {
|
||||
plog.G(ctx).Infof("Workload %s/%s has already been injected with sidecar", connectNamespace, workload)
|
||||
plog.G(ctx).Infof("Workload %s/%s has already been injected with sidecar", managerNamespace, workload)
|
||||
return nil
|
||||
}
|
||||
|
||||
enableIPv6, _ := util.DetectPodSupportIPv6(ctx, f, connectNamespace)
|
||||
enableIPv6, _ := util.DetectPodSupportIPv6(ctx, f, managerNamespace)
|
||||
// (1) add mesh container
|
||||
AddMeshContainer(templateSpec, object.Namespace, nodeID, enableIPv6, connectNamespace, secret, image)
|
||||
AddMeshContainer(templateSpec, object.Namespace, nodeID, enableIPv6, managerNamespace, secret, image)
|
||||
helper := pkgresource.NewHelper(object.Client, object.Mapping)
|
||||
ps := []P{
|
||||
{
|
||||
|
@@ -24,7 +24,7 @@ import (
|
||||
util2 "github.com/wencaiwulue/kubevpn/v2/pkg/util"
|
||||
)
|
||||
|
||||
func InjectVPNSidecar(ctx context.Context, nodeID string, f util.Factory, connectNamespace string, object *resource.Info, c util2.PodRouteConfig, secret *v1.Secret, image string) error {
|
||||
func InjectVPNSidecar(ctx context.Context, nodeID string, f util.Factory, managerNamespace string, object *resource.Info, c util2.PodRouteConfig, secret *v1.Secret, image string) error {
|
||||
u := object.Object.(*unstructured.Unstructured)
|
||||
|
||||
podTempSpec, path, err := util2.GetPodTemplateSpecPath(u)
|
||||
@@ -44,13 +44,13 @@ func InjectVPNSidecar(ctx context.Context, nodeID string, f util.Factory, connec
|
||||
for _, port := range ports {
|
||||
portmap[port.ContainerPort] = fmt.Sprintf("%d", port.ContainerPort)
|
||||
}
|
||||
err = addEnvoyConfig(clientset.CoreV1().ConfigMaps(connectNamespace), object.Namespace, nodeID, c, nil, controlplane.ConvertContainerPort(ports...), portmap)
|
||||
err = addEnvoyConfig(clientset.CoreV1().ConfigMaps(managerNamespace), object.Namespace, nodeID, c, nil, controlplane.ConvertContainerPort(ports...), portmap)
|
||||
if err != nil {
|
||||
plog.G(ctx).Errorf("Failed to add envoy config: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
AddContainer(&podTempSpec.Spec, c, connectNamespace, secret, image)
|
||||
AddContainer(&podTempSpec.Spec, c, managerNamespace, secret, image)
|
||||
|
||||
workload := fmt.Sprintf("%s/%s", object.Mapping.Resource.Resource, object.Name)
|
||||
helper := resource.NewHelper(object.Client, object.Mapping)
|
||||
|
@@ -254,3 +254,11 @@ func DetectSupportIPv6() (bool, error) {
|
||||
}
|
||||
return disableIPv6 == 0, nil
|
||||
}
|
||||
|
||||
func IsValidCIDR(str string) bool {
|
||||
_, _, err := net.ParseCIDR(str)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
@@ -11,7 +11,6 @@ import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/kubectl/pkg/cmd/util/podcmd"
|
||||
"k8s.io/utils/ptr"
|
||||
|
||||
@@ -84,16 +83,21 @@ func (h *admissionReviewHandler) handleCreate(ar v1.AdmissionReview) *v1.Admissi
|
||||
// 2) release old ip
|
||||
h.Lock()
|
||||
defer h.Unlock()
|
||||
var ips []net.IP
|
||||
var ipv4, ipv6 net.IP
|
||||
for k := 0; k < len(container.Env); k++ {
|
||||
envVar := container.Env[k]
|
||||
if sets.New[string](config.EnvInboundPodTunIPv4, config.EnvInboundPodTunIPv6).Has(envVar.Name) && envVar.Value != "" {
|
||||
if config.EnvInboundPodTunIPv4 == envVar.Name && envVar.Value != "" {
|
||||
if ip, _, _ := net.ParseCIDR(envVar.Value); ip != nil {
|
||||
ips = append(ips, ip)
|
||||
ipv4 = ip
|
||||
}
|
||||
}
|
||||
if config.EnvInboundPodTunIPv6 == envVar.Name && envVar.Value != "" {
|
||||
if ip, _, _ := net.ParseCIDR(envVar.Value); ip != nil {
|
||||
ipv6 = ip
|
||||
}
|
||||
}
|
||||
}
|
||||
_ = h.dhcp.ReleaseIP(context.Background(), ips...)
|
||||
_ = h.dhcp.ReleaseIP(context.Background(), ipv4, ipv6)
|
||||
|
||||
// 3) rent new ip
|
||||
var v4, v6 *net.IPNet
|
||||
@@ -171,22 +175,27 @@ func (h *admissionReviewHandler) handleDelete(ar v1.AdmissionReview) *v1.Admissi
|
||||
}
|
||||
|
||||
// 2) release ip
|
||||
var ips []net.IP
|
||||
var ipv4, ipv6 net.IP
|
||||
for _, envVar := range container.Env {
|
||||
if envVar.Name == config.EnvInboundPodTunIPv4 || envVar.Name == config.EnvInboundPodTunIPv6 {
|
||||
if envVar.Name == config.EnvInboundPodTunIPv4 {
|
||||
if ip, _, err := net.ParseCIDR(envVar.Value); err == nil {
|
||||
ips = append(ips, ip)
|
||||
ipv4 = ip
|
||||
}
|
||||
}
|
||||
if envVar.Name == config.EnvInboundPodTunIPv6 {
|
||||
if ip, _, err := net.ParseCIDR(envVar.Value); err == nil {
|
||||
ipv6 = ip
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(ips) != 0 {
|
||||
if ipv4 != nil || ipv6 != nil {
|
||||
h.Lock()
|
||||
defer h.Unlock()
|
||||
err := h.dhcp.ReleaseIP(context.Background(), ips...)
|
||||
err := h.dhcp.ReleaseIP(context.Background(), ipv4, ipv6)
|
||||
if err != nil {
|
||||
plog.G(context.Background()).Errorf("Failed to release IP %v to DHCP server: %v", ips, err)
|
||||
plog.G(context.Background()).Errorf("Failed to release IPv4 %v IPv6 %s to DHCP server: %v", ipv4, ipv6, err)
|
||||
} else {
|
||||
plog.G(context.Background()).Debugf("Release IP %v to DHCP server", ips)
|
||||
plog.G(context.Background()).Debugf("Release IPv4 %v IPv6 %v to DHCP server", ipv4, ipv6)
|
||||
}
|
||||
}
|
||||
return &v1.AdmissionResponse{Allowed: true}
|
||||
|
Reference in New Issue
Block a user