github.com/caos/orbos@v1.5.14-0.20221103111702-e6cd0cea7ad4/internal/operator/nodeagent/dep/keepalived/dep.go (about)

     1  package keepalived
     2  
     3  import (
     4  	"bytes"
     5  	"io/ioutil"
     6  	"os"
     7  	"os/exec"
     8  	"regexp"
     9  	"strconv"
    10  	"strings"
    11  
    12  	"github.com/caos/orbos/internal/operator/common"
    13  	"github.com/caos/orbos/internal/operator/nodeagent"
    14  	"github.com/caos/orbos/internal/operator/nodeagent/dep"
    15  	"github.com/caos/orbos/internal/operator/nodeagent/dep/middleware"
    16  	"github.com/caos/orbos/internal/operator/nodeagent/dep/selinux"
    17  	"github.com/caos/orbos/mntr"
    18  )
    19  
    20  type Installer interface {
    21  	isKeepalived()
    22  	nodeagent.Installer
    23  }
    24  type keepaliveDDep struct {
    25  	monitor    mntr.Monitor
    26  	manager    *dep.PackageManager
    27  	systemd    *dep.SystemD
    28  	peerAuth   string
    29  	os         dep.OperatingSystem
    30  	normalizer *regexp.Regexp
    31  }
    32  
    33  func New(monitor mntr.Monitor, manager *dep.PackageManager, systemd *dep.SystemD, os dep.OperatingSystem, cipher string) Installer {
    34  	return &keepaliveDDep{monitor, manager, systemd, cipher[:8], os, regexp.MustCompile(`\d+\.\d+\.\d+`)}
    35  }
    36  
    37  func (keepaliveDDep) isKeepalived() {}
    38  
    39  func (keepaliveDDep) Is(other nodeagent.Installer) bool {
    40  	_, ok := middleware.Unwrap(other).(Installer)
    41  	return ok
    42  }
    43  
    44  func (keepaliveDDep) String() string { return "Keepalived" }
    45  
    46  func (*keepaliveDDep) Equals(other nodeagent.Installer) bool {
    47  	_, ok := other.(*keepaliveDDep)
    48  	return ok
    49  }
    50  
    51  func (keepaliveDDep) InstalledFilter() []string {
    52  	return []string{"keepalived"}
    53  }
    54  
    55  func (s *keepaliveDDep) Current() (pkg common.Package, err error) {
    56  
    57  	defer func() {
    58  		if err == nil && pkg.Version != "" {
    59  			err = selinux.Current(s.os, &pkg)
    60  		}
    61  	}()
    62  
    63  	if !s.systemd.Active("keepalived") {
    64  		return pkg, err
    65  	}
    66  
    67  	installed := s.manager.CurrentVersions("keepalived")
    68  	if len(installed) == 0 {
    69  		return pkg, nil
    70  	}
    71  	pkg.Version = "v" + s.normalizer.FindString(installed[0].Version)
    72  
    73  	config, err := ioutil.ReadFile("/etc/keepalived/keepalived.conf")
    74  	if err != nil {
    75  		if os.IsNotExist(err) {
    76  			return pkg, nil
    77  		}
    78  		return pkg, err
    79  	}
    80  
    81  	redacted := new(bytes.Buffer)
    82  	defer redacted.Reset()
    83  
    84  	if err := dep.Manipulate(bytes.NewReader(config), redacted, nil, nil, func(line string) *string {
    85  		searchString := "auth_pass "
    86  		if strings.Contains(line, searchString) {
    87  			line = line[0:strings.Index(line, searchString)+len(searchString)] + "[ REDACTED ]"
    88  		}
    89  		return &line
    90  	}); err != nil {
    91  		return pkg, err
    92  	}
    93  	pkg.Config = map[string]string{
    94  		"keepalived.conf": redacted.String(),
    95  	}
    96  
    97  	notifymaster, err := ioutil.ReadFile("/etc/keepalived/notifymaster.sh")
    98  	if os.IsNotExist(err) {
    99  		err = nil
   100  	}
   101  	if err != nil {
   102  		return pkg, err
   103  	}
   104  
   105  	if string(notifymaster) != "" {
   106  		pkg.Config["notifymaster.sh"] = string(notifymaster)
   107  	}
   108  
   109  	authCheck, err := ioutil.ReadFile("/etc/keepalived/authcheck.sh")
   110  	if os.IsNotExist(err) {
   111  		err = nil
   112  	}
   113  	if err != nil {
   114  		return pkg, err
   115  	}
   116  	if string(authCheck) != "" {
   117  		pkg.Config["authcheck.sh"] = string(authCheck)
   118  		var exitCode int
   119  		if err := exec.Command("/etc/keepalived/authcheck.sh").Run(); err != nil {
   120  			exitCode = err.(*exec.ExitError).ExitCode()
   121  		}
   122  		pkg.Config["authcheckexitcode"] = strconv.Itoa(exitCode)
   123  	}
   124  
   125  	return pkg, err
   126  }
   127  
   128  func (s *keepaliveDDep) Ensure(remove common.Package, ensure common.Package, _ bool) error {
   129  
   130  	if err := selinux.EnsurePermissive(s.monitor, s.os, remove); err != nil {
   131  		return err
   132  	}
   133  
   134  	ensureCfg, ok := ensure.Config["keepalived.conf"]
   135  	if !ok {
   136  		if err := s.systemd.Disable("keepalived"); err != nil {
   137  			return err
   138  		}
   139  		return os.Remove("/etc/keepalived/keepalived.conf")
   140  	}
   141  
   142  	if err := s.manager.Install(&dep.Software{
   143  		Package: "keepalived",
   144  		Version: strings.TrimLeft(ensure.Version, "v"),
   145  	}); err != nil {
   146  		return err
   147  	}
   148  
   149  	if err := os.MkdirAll("/etc/keepalived", 0700); err != nil {
   150  		return err
   151  	}
   152  
   153  	if err := ioutil.WriteFile("/etc/keepalived/keepalived.conf", []byte(strings.ReplaceAll(ensureCfg, "[ REDACTED ]", s.peerAuth)), 0600); err != nil {
   154  		return err
   155  	}
   156  
   157  	if notifyMaster, ok := ensure.Config["notifymaster.sh"]; ok {
   158  		if err := ioutil.WriteFile("/etc/keepalived/notifymaster.sh", []byte(notifyMaster), 0777); err != nil {
   159  			return err
   160  		}
   161  	}
   162  
   163  	if authCheck, ok := ensure.Config["authcheck.sh"]; ok {
   164  		if err := ioutil.WriteFile("/etc/keepalived/authcheck.sh", []byte(authCheck), 0777); err != nil {
   165  			return err
   166  		}
   167  	}
   168  
   169  	if err := s.systemd.Enable("keepalived"); err != nil {
   170  		return err
   171  	}
   172  
   173  	return s.systemd.Start("keepalived")
   174  }