From 7bb0698f774080e4514352e229f6fb9900b49e3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9E=D0=BB=D0=B5=D0=B3=20=D0=91=D0=BE=D1=80=D0=BE=D0=B4?= =?UTF-8?q?=D0=B8=D0=BD?= Date: Thu, 9 Apr 2026 17:50:12 +0200 Subject: [PATCH] beta contoller implanted --- Makefile.am | 4 +-- Makefile.in | 4 +-- app/config/config.go | 47 +++++++++++++++++++--------- app/config/variant.go | 10 +++--- app/control/kubeset.go | 2 +- app/control/svccont.go | 29 +++++++++++++++-- app/operator/oper.go | 3 +- app/server/server.go | 71 ++++++++++++++++++++++++++++++++++-------- initrc/minilbd.service | 4 +-- 9 files changed, 131 insertions(+), 43 deletions(-) diff --git a/Makefile.am b/Makefile.am index 1de7edf..860301d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -121,8 +121,8 @@ format: done run: - test -z $(DESTDIR)$(srv_logdir) || $(MKDIR_P) $(DESTDIR)$(srv_logdir) - test -z $(DESTDIR)$(srv_rundir) || $(MKDIR_P) $(DESTDIR)$(srv_rundir) +# test -z $(DESTDIR)$(srv_logdir) || $(MKDIR_P) $(DESTDIR)$(srv_logdir) +# test -z $(DESTDIR)$(srv_rundir) || $(MKDIR_P) $(DESTDIR)$(srv_rundir) env CGO_ENABLED=0 $(GO) run $(GOFLAGS) ./cmd/minilbd/... --asDaemon=false BUILD_DIR= $(shell pwd)/TMP.build diff --git a/Makefile.in b/Makefile.in index 51a366a..4d34c3f 100644 --- a/Makefile.in +++ b/Makefile.in @@ -908,8 +908,8 @@ format: done run: - test -z $(DESTDIR)$(srv_logdir) || $(MKDIR_P) $(DESTDIR)$(srv_logdir) - test -z $(DESTDIR)$(srv_rundir) || $(MKDIR_P) $(DESTDIR)$(srv_rundir) +# test -z $(DESTDIR)$(srv_logdir) || $(MKDIR_P) $(DESTDIR)$(srv_logdir) +# test -z $(DESTDIR)$(srv_rundir) || $(MKDIR_P) $(DESTDIR)$(srv_rundir) env CGO_ENABLED=0 $(GO) run $(GOFLAGS) ./cmd/minilbd/... --asDaemon=false $(DIST_ARCHIVES): dist diff --git a/app/config/config.go b/app/config/config.go index 45862f8..9763cf7 100644 --- a/app/config/config.go +++ b/app/config/config.go @@ -3,6 +3,7 @@ package config import ( "errors" "fmt" + "net/netip" "os" "path/filepath" @@ -29,14 +30,17 @@ type Auth struct { } type Config struct { - Service Service `json:"service" yaml:"service"` - Auths []Auth `json:"auths" yaml:"auths"` - Hostname string `json:"hostname" yaml:"hostname"` - LogPath string `json:"logfile" yaml:"logfile"` - RunPath string `json:"runfile" yaml:"runfile"` - AsDaemon bool `json:"asDaemon" yaml:"asDaemon"` - LogLimit int64 `json:"logLimit" yaml:logLimit` - RunUser string `json:"runUser" yaml:runUser` + Service Service `json:"service" yaml:"service"` + Auths []Auth `json:"auths" yaml:"auths"` + Hostname string `json:"hostname" yaml:"hostname"` + LogPath string `json:"logfile" yaml:"logfile"` + RunPath string `json:"runfile" yaml:"runfile"` + AsDaemon bool `json:"asDaemon" yaml:"asDaemon"` + LogLimit int64 `json:"logLimit" yaml:"logLimit"` + RunUser string `json:"runUser" yaml:"runUser"` + KubeconfPath string `json:"kubeconfPath" yaml:"kubeconfPath"` + ExtAddress string `json:"extAddress" yaml:"extAddress"` + Kubeconf []byte `json:"-" yaml:"-"` } func NewConfig() (*Config, error) { @@ -44,9 +48,11 @@ func NewConfig() (*Config, error) { Service: Service{ Port: client.DefaultServicePort, }, - AsDaemon: false, - LogLimit: 1024 * 1024 * 10, // 10 Mb - RunUser: "daemon", + AsDaemon: false, + LogLimit: 1024 * 1024 * 10, // 10 Mb + RunUser: "daemon", + KubeconfPath: "kubeconf.yaml", + ExtAddress: "127.0.0.1", } hostname, err := os.Hostname() if err != nil { @@ -70,20 +76,31 @@ func (conf *Config) Read() error { if err != nil { return err } + if !filepath.IsAbs(conf.KubeconfPath) { + conf.KubeconfPath = filepath.Join(confdirPath, conf.KubeconfPath) + } + kubeconfBytes, err := os.ReadFile(conf.KubeconfPath) + if err != nil { + err = fmt.Errorf("Cannot read kubeconf in path %s: %v", conf.KubeconfPath, err) + return err + } + conf.Kubeconf = kubeconfBytes return err } func (conf *Config) Validate() error { - var err []error + var errs []error for i := range conf.Auths { if conf.Auths[i].Username == "" { - err = append(err, errors.New("Username must be set")) + errs = append(errs, errors.New("Username must be set")) } if conf.Auths[i].Password == "" { - err = append(err, errors.New("Password must be set")) + errs = append(errs, errors.New("Password must be set")) } } - return errors.Join(err...) + _, err := netip.ParseAddr(conf.ExtAddress) + errs = append(errs, err) + return errors.Join(errs...) } func (conf *Config) YAML() (string, error) { diff --git a/app/config/variant.go b/app/config/variant.go index 79c7709..ee2cfe5 100644 --- a/app/config/variant.go +++ b/app/config/variant.go @@ -1,10 +1,10 @@ package config const ( - confdirPath = "/etc/minilb" - rundirPath = "/var/run/minilb" - logdirPath = "/var/log/minilb" - datadirPath = "/var/lib/minilb" + confdirPath = "/home/ziggi/Projects/minilb/etc/minilb" + rundirPath = "/home/ziggi/Projects/minilb/tmp/run" + logdirPath = "/home/ziggi/Projects/minilb/tmp/log" + datadirPath = "/home/ziggi/Projects/minilb/tmp/data" pkgVersion = "0.0.1" - runUser = "daemon" + runUser = "ziggi" ) diff --git a/app/control/kubeset.go b/app/control/kubeset.go index 8bc0cab..72000b6 100644 --- a/app/control/kubeset.go +++ b/app/control/kubeset.go @@ -5,7 +5,7 @@ import ( kubeclicmd "k8s.io/client-go/tools/clientcmd" ) -func makeClientset(kubeconf []byte) (kubeclient.Interface, error) { +func MakeClientset(kubeconf []byte) (kubeclient.Interface, error) { var res kubeclient.Interface var err error clientConfig, err := kubeclicmd.NewClientConfigFromBytes(kubeconf) diff --git a/app/control/svccont.go b/app/control/svccont.go index 1476bfa..8b1cd23 100644 --- a/app/control/svccont.go +++ b/app/control/svccont.go @@ -17,6 +17,28 @@ import ( "helmet/app/logger" ) +type Proxy interface { + CreateOrUpdateForwarder(ctx context.Context, proto string, lport, dport uint32, addrs ...string) error + DeleteForwarder(ctx context.Context, proto string, lport uint32) error +} + +type Dummyproxy struct { + log *logger.Logger +} + +func NewDummyproxy() Proxy { + return &Dummyproxy{ + log: logger.NewLogger("dummyproxy"), + } +} + +func (prox *Dummyproxy) CreateOrUpdateForwarder(ctx context.Context, proto string, lport, dport uint32, addrs ...string) error { + return nil +} +func (prox *Dummyproxy) DeleteForwarder(ctx context.Context, proto string, lport uint32) error { + return nil +} + type Controller struct { lbaddr string clientset k8client.Interface @@ -24,11 +46,13 @@ type Controller struct { ctx context.Context cancel context.CancelFunc log *logger.Logger + proxy Proxy } -func NewController(clientset k8client.Interface, lbaddr string) *Controller { +func NewController(proxy Proxy, clientset k8client.Interface, lbaddr string) *Controller { ctx, cancel := context.WithCancel(context.Background()) cont := &Controller{ + proxy: proxy, clientset: clientset, ctx: ctx, cancel: cancel, @@ -40,7 +64,7 @@ func NewController(clientset k8client.Interface, lbaddr string) *Controller { func (cont *Controller) Run() { cont.log.Debugf("Start controller") - factory := k8inform.NewSharedInformerFactory(cont.clientset, time.Minute*10) + factory := k8inform.NewSharedInformerFactory(cont.clientset, 10*time.Second) defer factory.Shutdown() serviceInformer := factory.Core().V1().Services().Informer() @@ -57,6 +81,7 @@ func (cont *Controller) Run() { synced := factory.WaitForCacheSync(ctx.Done()) for _, sync := range synced { if !sync { + cont.log.Errorf("Cannot sync controller") return } } diff --git a/app/operator/oper.go b/app/operator/oper.go index 8cf184f..63584d3 100644 --- a/app/operator/oper.go +++ b/app/operator/oper.go @@ -8,6 +8,7 @@ import ( type OperatorConfig struct { Auths []config.Auth + Proxy *rproxy.Proxy } type Operator struct { @@ -20,8 +21,8 @@ func NewOperator(conf *OperatorConfig) (*Operator, error) { var err error oper := &Operator{ auths: conf.Auths, + proxy: conf.Proxy, } oper.log = logger.NewLogger("operator") - oper.proxy = rproxy.NewProxy() return oper, err } diff --git a/app/server/server.go b/app/server/server.go index 3f6009c..ba38049 100644 --- a/app/server/server.go +++ b/app/server/server.go @@ -14,9 +14,11 @@ import ( "time" "helmet/app/config" + "helmet/app/control" "helmet/app/handler" "helmet/app/logger" "helmet/app/operator" + "helmet/app/rproxy" "helmet/app/service" "helmet/pkg/network" "helmet/pkg/x509crt" @@ -35,6 +37,8 @@ type Server struct { cancel context.CancelFunc wg sync.WaitGroup listen net.Listener + cont *control.Controller + proxy *rproxy.Proxy } func NewServer() (*Server, error) { @@ -69,21 +73,39 @@ func (srv *Server) Build() error { var err error srv.log.Infof("Build server") - // Get effective user uid/guid - usr, err := user.Lookup(srv.conf.RunUser) + currUser, err := user.Current() if err != nil { + err = fmt.Errorf("Error getting current user: %v\n", err) return err } - uid64, err := strconv.ParseInt(usr.Uid, 10, 64) + cuid64, err := strconv.ParseInt(currUser.Uid, 10, 64) if err != nil { return err } - gid64, err := strconv.ParseInt(usr.Gid, 10, 64) + cgid64, err := strconv.ParseInt(currUser.Gid, 10, 64) if err != nil { return err } - uid := int(uid64) - gid := int(gid64) + euid := int(cuid64) + egid := int(cgid64) + + if cuid64 == 0 { + // Get effective user uid/guid + usr, err := user.Lookup(srv.conf.RunUser) + if err != nil { + return err + } + uid64, err := strconv.ParseInt(usr.Uid, 10, 64) + if err != nil { + return err + } + gid64, err := strconv.ParseInt(usr.Gid, 10, 64) + if err != nil { + return err + } + euid = int(uid64) + egid = int(gid64) + } if srv.conf.AsDaemon { logDir := filepath.Dir(srv.conf.LogPath) @@ -92,7 +114,7 @@ func (srv *Server) Build() error { if err != nil { return err } - err = os.Chown(logDir, uid, gid) + err = os.Chown(logDir, euid, egid) if err != nil { return err } @@ -102,7 +124,7 @@ func (srv *Server) Build() error { if err != nil { return err } - err = os.Chown(runDir, uid, gid) + err = os.Chown(runDir, euid, egid) if err != nil { return err } @@ -111,17 +133,22 @@ func (srv *Server) Build() error { addrinfo := ":" + strconv.FormatUint(uint64(srv.conf.Service.Port), 10) listener, err := network.CreateListener(addrinfo) if err != nil { - return err + return fmt.Errorf("Cannot create listener: %v", err) } srv.listen = listener // Change effective user - err = syscall.Setuid(uid) - if err != nil { - return err + if cuid64 == 0 { + err = syscall.Setuid(euid) + if err != nil { + return fmt.Errorf("Cannot change running user: %v", err) + } } + + //return fmt.Errorf("Debug break") + uidstr := strconv.FormatInt(int64(syscall.Geteuid()), 10) - usr, err = user.LookupId(uidstr) + usr, err := user.LookupId(uidstr) if err != nil { return err } @@ -132,9 +159,23 @@ func (srv *Server) Build() error { if err != nil { return err } + // Create proxy + srv.proxy = rproxy.NewProxy() + + // Create controller + clientset, err := control.MakeClientset(srv.conf.Kubeconf) + if err != nil { + return err + } + srv.cont = control.NewController(srv.proxy, clientset, srv.conf.ExtAddress) + if err != nil { + return err + } + // Create operator operatorConfig := &operator.OperatorConfig{ Auths: srv.conf.Auths, + Proxy: srv.proxy, //Database: srv.db, } srv.oper, err = operator.NewOperator(operatorConfig) @@ -229,6 +270,7 @@ func (srv *Server) Run() error { // Run service startService := func(svc *service.Service, done chan error) { + srv.log.Infof("Run rpc service") err = svc.Run() if err != nil { srv.log.Errorf("Service error: %v", err) @@ -236,6 +278,9 @@ func (srv *Server) Run() error { } } go startService(srv.svc, done) + // Run controller + srv.log.Infof("Run controller") + go srv.cont.Run() signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) var signal os.Signal diff --git a/initrc/minilbd.service b/initrc/minilbd.service index 2455c55..e056e6a 100644 --- a/initrc/minilbd.service +++ b/initrc/minilbd.service @@ -3,10 +3,10 @@ Description=minilbd [Service] Type=forking -ExecStart=/usr/sbin/minilbd --asDaemon=true +ExecStart=/usr/local/sbin/minilbd --asDaemon=true ExecReload=/bin/kill -HUP $MAINPID ExecRestart=/bin/kill -HUP $MAINPID -ExecStartPre=/usr/bin/install -d -o daemon /var/run/minilb /var/log/minilb +ExecStartPre=/usr/bin/install -d -o ziggi /home/ziggi/Projects/minilb/tmp/run /home/ziggi/Projects/minilb/tmp/log [Install] WantedBy=multi-user.target