Skip to content

Commit

Permalink
Sapservices gatherer wip
Browse files Browse the repository at this point in the history
  • Loading branch information
CDimonaco committed Oct 19, 2023
1 parent c1e5123 commit 2c67751
Showing 1 changed file with 183 additions and 0 deletions.
183 changes: 183 additions & 0 deletions internal/factsengine/gatherers/sapservices.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
package gatherers

import (
"bufio"
"encoding/json"
"fmt"
"regexp"
"strings"

log "github.com/sirupsen/logrus"
"github.com/spf13/afero"
"github.com/trento-project/agent/pkg/factsengine/entities"
)

type SapServicesStartupKind string

const (
SapServicesSystemdStartup SapServicesStartupKind = "systemd"
SapServicesSapstartStartup SapServicesStartupKind = "sapstartsrv"
sapServicesDefaultPath = "/usr/sap/sapservices"
SapServicesGathererName = "sapservices"
)

// nolint:gochecknoglobals
var (
SapServicesParsingError = entities.FactGatheringError{
Type: "sap-services-parsing-error",
Message: "error parsing the sap services file",
}
SapServicesFileError = entities.FactGatheringError{
Type: "sap-services-parsing-error",
Message: "error reading the sap services file",
}
SapstartSIDExtractionPattern = regexp.MustCompile(`?s)pf=([^[:space:]]+)/(.*?)_`)

Check failure on line 34 in internal/factsengine/gatherers/sapservices.go

View workflow job for this annotation

GitHub Actions / static-analysis

SA1000: error parsing regexp: missing argument to repetition operator: `?` (staticcheck)
SystemdSIDExtractionPattern = regexp.MustCompile(`(?s)start SAP(.*?)_.* `)
)

// #!/bin/sh
// limit.descriptors=1048576
// LD_LIBRARY_PATH=/usr/sap/HS1/HDB11/exe:$LD_LIBRARY_PATH;export LD_LIBRARY_PATH;/usr/sap/HS1/HDB11/exe/sapstartsrv pf=/usr/sap/HS1/SYS/profile/HS1_HDB11_s41db -D -u hs1adm

Check failure on line 40 in internal/factsengine/gatherers/sapservices.go

View workflow job for this annotation

GitHub Actions / static-analysis

line is 173 characters (lll)
// LD_LIBRARY_PATH=/usr/sap/S41/ASCS41/exe:$LD_LIBRARY_PATH; export LD_LIBRARY_PATH; /usr/sap/S41/ASCS41/exe/sapstartsrv pf=/usr/sap/S41/SYS/profile/S41_ASCS41_s41app -D -u s41adm

Check failure on line 41 in internal/factsengine/gatherers/sapservices.go

View workflow job for this annotation

GitHub Actions / static-analysis

line is 179 characters (lll)
// LD_LIBRARY_PATH=/usr/sap/S41/D40/exe:$LD_LIBRARY_PATH; export LD_LIBRARY_PATH; /usr/sap/S41/D40/exe/sapstartsrv pf=/usr/sap/S41/SYS/profile/S41_D40_s41app -D -u s41adm

Check failure on line 42 in internal/factsengine/gatherers/sapservices.go

View workflow job for this annotation

GitHub Actions / static-analysis

line is 170 characters (lll)
// systemctl --no-ask-password start SAPS41_40 # sapstartsrv pf=/sapmnt/S41/profile/S41_D40_s41app
// systemctl --no-ask-password start SAPS41_41 # sapstartsrv pf=/sapmnt/S41/profile/S41_ASCS41_s41app

type SapServicesEntry struct {
SID string `json:"sid"`
Kind SapServicesStartupKind `json:"kind"`
Content string `json:"content"`
}

func systemdStartup(sapServicesContent string) bool {
return strings.Contains(sapServicesContent, "systemctl")
}

func sapstartStartup(sapServicesContent string) bool {
return strings.Contains(sapServicesContent, "sapstartsrv")
}

func extractSIDFromSystemdService(sapServicesContent string) string {
matches := SystemdSIDExtractionPattern.FindStringSubmatch(sapServicesContent)
if len(matches) != 2 {
return ""
}
return matches[1]
}

func extractSIDFromSapstartService(sapServicesContent string) string {
matches := SapstartSIDExtractionPattern.FindStringSubmatch(sapServicesContent)
if len(matches) != 2 {
return ""
}
return matches[1]
}

type SapServices struct {
fs afero.Fs
servicesFilePath string
}

func NewSapServicesGatherer(servicesFilePath string, fs afero.Fs) *SapServices {
return &SapServices{
servicesFilePath: servicesFilePath,
fs: fs,
}
}

func NewDefaultSapServicesGatherer() *SapServices {
return &SapServices{servicesFilePath: sapServicesDefaultPath, fs: afero.NewOsFs()}
}

func (s *SapServices) Gather(factsRequests []entities.FactRequest) ([]entities.Fact, error) {
facts := []entities.Fact{}
log.Infof("Starting %s facts gathering process", SapServicesGathererName)

entries, err := s.getSapServicesFileEntries()
if err != nil {
return nil, err
}

factValues, err := convertSapServicesEntriesToFactValue(entries)
if err != nil {
return nil, SapServicesParsingError.Wrap(err.Error())
}

for _, requestedFact := range factsRequests {
fact := entities.NewFactGatheredWithRequest(requestedFact, factValues)

facts = append(facts, fact)
}

log.Infof("Requested %s facts gathered", SapServicesGathererName)
return facts, nil
}

func (s *SapServices) getSapServicesFileEntries() ([]SapServicesEntry, error) {
f, err := s.fs.Open(s.servicesFilePath)
if err != nil {
return nil, SapServicesFileError.Wrap(err.Error())
}

defer func() {
err := f.Close()
if err != nil {
log.Error(err)
}
}()

fileScanner := bufio.NewScanner(f)
fileScanner.Split(bufio.ScanLines)

var entries []SapServicesEntry

for fileScanner.Scan() {
scannedLine := fileScanner.Text()
if strings.HasPrefix(scannedLine, "#") || scannedLine == "" {
continue
}
entry := SapServicesEntry{}
entry.Content = scannedLine

if systemdStartup(scannedLine) {
entry.Kind = SapServicesSystemdStartup
sid := extractSIDFromSystemdService(scannedLine)
if sid == "" {
return nil, SapServicesParsingError.Wrap(fmt.Sprintf("could not extract sid from systemd sap services entry: %s", scannedLine))

Check failure on line 146 in internal/factsengine/gatherers/sapservices.go

View workflow job for this annotation

GitHub Actions / static-analysis

line is 131 characters (lll)
}
entry.SID = sid
}

if sapstartStartup(scannedLine) {
entry.Kind = SapServicesSapstartStartup
sid := extractSIDFromSapstartService(scannedLine)
if sid == "" {
return nil, SapServicesParsingError.Wrap(fmt.Sprintf("could not extract sid from sapstartsrv sap services entry: %s", scannedLine))

Check failure on line 155 in internal/factsengine/gatherers/sapservices.go

View workflow job for this annotation

GitHub Actions / static-analysis

line is 135 characters (lll)
}
entry.SID = sid
}

if entry.Kind == "" {
return nil, SapServicesParsingError.Wrap(fmt.Sprintf("could not identify startup service kind for sap services entry: %s", scannedLine))

Check failure on line 161 in internal/factsengine/gatherers/sapservices.go

View workflow job for this annotation

GitHub Actions / static-analysis

line is 139 characters (lll)
}

entries = append(entries, entry)
}

return entries, nil
}

func convertSapServicesEntriesToFactValue(entries []SapServicesEntry) (entities.FactValue, error) {
marshalled, err := json.Marshal(&entries)
if err != nil {
return nil, err
}

var unmarshalled []interface{}
err = json.Unmarshal(marshalled, &unmarshalled)
if err != nil {
return nil, err
}

return entities.NewFactValue(unmarshalled, entities.WithStringConversion())
}

0 comments on commit 2c67751

Please sign in to comment.