Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sapservices gatherer improvement #337

Merged
merged 3 commits into from
Jun 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 32 additions & 22 deletions internal/factsengine/gatherers/sapservices.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,15 @@ var (
Type: "sap-services-reading-error",
Message: "error reading the sapservices file",
}
SapstartSIDExtractionPattern = regexp.MustCompile(`(?s)pf=[^[:space:]]+/(.*?)_.*_.*`)
SystemdSIDExtractionPattern = regexp.MustCompile(`(?s)start SAP(.*?)_.*`)
SapstartSIDExtractionPattern = regexp.MustCompile(`(?s)pf=[^[:space:]]+/(.*?)_(.*(\d{2}))_.*`)
arbulu89 marked this conversation as resolved.
Show resolved Hide resolved
SystemdSIDExtractionPattern = regexp.MustCompile(`(?s)start SAP(.*?)_(\d{2})`)
)

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

func systemdStartup(sapServicesContent string) bool {
Expand All @@ -49,20 +50,20 @@ func sapstartStartup(sapServicesContent string) bool {
return strings.Contains(sapServicesContent, "sapstartsrv")
}

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

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

type SapServices struct {
Expand Down Expand Up @@ -129,29 +130,37 @@ func (s *SapServices) getSapServicesFileEntries() ([]SapServicesEntry, error) {
continue
}

// If the line does not start with a comment but has a comment in the middle, cut the comment
cleanedLine, _, _ := strings.Cut(scannedLine, "#")
scannedLine = cleanedLine

var kind SapServicesStartupKind
var sid string
var instance string

if systemdStartup(scannedLine) {
kind = SapServicesSystemdStartup
extractedSID := extractSIDFromSystemdService(scannedLine)
if extractedSID == "" {
extractedSID, extractedInstance := extractInfoFromSystemdService(scannedLine)
if extractedSID == "" || extractedInstance == "" {
return nil, SapServicesParsingError.Wrap(
fmt.Sprintf("could not extract sid from systemd SAP services entry: %s", scannedLine),
fmt.Sprintf("could not extract values from systemd SAP services entry: %s", scannedLine),
)
}

sid = extractedSID
instance = extractedInstance
}

if sapstartStartup(scannedLine) {
kind = SapServicesSapstartStartup
extractedSID := extractSIDFromSapstartService(scannedLine)
if extractedSID == "" {
extractedSID, extractedInstance := extractInfoFromSapstartService(scannedLine)
if extractedSID == "" || extractedInstance == "" {
return nil, SapServicesParsingError.Wrap(
fmt.Sprintf("could not extract sid from sapstartsrv SAP services entry: %s", scannedLine),
fmt.Sprintf("could not extract values from sapstartsrv SAP services entry: %s", scannedLine),
)
}
sid = extractedSID
instance = extractedInstance
}

if kind == "" {
Expand All @@ -160,9 +169,10 @@ func (s *SapServices) getSapServicesFileEntries() ([]SapServicesEntry, error) {
}

entry := SapServicesEntry{
SID: sid,
Kind: kind,
Content: scannedLine,
SID: sid,
Kind: kind,
Content: scannedLine,
Instance: instance,
}

entries = append(entries, entry)
Expand Down
129 changes: 115 additions & 14 deletions internal/factsengine/gatherers/sapservices_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,29 @@ func (s *SapServicesGathererSuite) TestSapServicesGathererFileNotFound() {
s.EqualError(err, "fact gathering error: sap-services-reading-error - error reading the sapservices file: open /usr/sap/sapservices: file does not exist")
}

func (s *SapServicesGathererSuite) TestSapServicesGathererInstanceNotIdentifiedSystemd() {
tFs := afero.NewMemMapFs()
_ = afero.WriteFile(tFs, "/usr/sap/sapservices", []byte(`
#!/bin/sh
limit.descriptors=1048576
systemctl --no-ask-password start SAPS41_0
systemctl --no-ask-password start SAPS41_1
`), 0777)

fr := []entities.FactRequest{
{
Name: "sapservices",
CheckID: "check1",
Gatherer: "sapservices",
},
}

g := gatherers.NewSapServicesGatherer("/usr/sap/sapservices", tFs)
result, err := g.Gather(fr)
s.Nil(result)
s.EqualError(err, "fact gathering error: sap-services-parsing-error - error parsing the sapservices file: could not extract values from systemd SAP services entry: systemctl --no-ask-password start SAPS41_0 ")

}
func (s *SapServicesGathererSuite) TestSapServicesGathererSIDNotIdentifiedSystemd() {
tFs := afero.NewMemMapFs()
_ = afero.WriteFile(tFs, "/usr/sap/sapservices", []byte(`
Expand All @@ -54,7 +77,7 @@ systemctl --no-ask-password start SADS41_41
g := gatherers.NewSapServicesGatherer("/usr/sap/sapservices", tFs)
result, err := g.Gather(fr)
s.Nil(result)
s.EqualError(err, "fact gathering error: sap-services-parsing-error - error parsing the sapservices file: could not extract sid from systemd SAP services entry: systemctl --no-ask-password start SADS41_41")
s.EqualError(err, "fact gathering error: sap-services-parsing-error - error parsing the sapservices file: could not extract values from systemd SAP services entry: systemctl --no-ask-password start SADS41_41")

}

Expand All @@ -79,7 +102,31 @@ LD_LIBRARY_PATH=/usr/sap/S41/D40/exe:$LD_LIBRARY_PATH; export LD_LIBRARY_PATH; /
g := gatherers.NewSapServicesGatherer("/usr/sap/sapservices", tFs)
result, err := g.Gather(fr)
s.Nil(result)
s.EqualError(err, "fact gathering error: sap-services-parsing-error - error parsing the sapservices file: could not extract sid from sapstartsrv SAP services entry: 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/HS1HDB11_s41db -D -u hs1adm")
s.EqualError(err, "fact gathering error: sap-services-parsing-error - error parsing the sapservices file: could not extract values from sapstartsrv SAP services entry: 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/HS1HDB11_s41db -D -u hs1adm")
}

func (s *SapServicesGathererSuite) TestSapServicesGathererInstanceNotIdentifiedSapstart() {
tFs := afero.NewMemMapFs()
_ = afero.WriteFile(tFs, "/usr/sap/sapservices", []byte(`
#!/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_HDB1_s41db -D -u hs1adm
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
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
`), 0777)

fr := []entities.FactRequest{
{
Name: "sapservices",
CheckID: "check1",
Gatherer: "sapservices",
},
}

g := gatherers.NewSapServicesGatherer("/usr/sap/sapservices", tFs)
result, err := g.Gather(fr)
s.Nil(result)
s.EqualError(err, "fact gathering error: sap-services-parsing-error - error parsing the sapservices file: could not extract values from sapstartsrv SAP services entry: 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_HDB1_s41db -D -u hs1adm")
}

func (s *SapServicesGathererSuite) TestSapServicesGathererSuccessSapstart() { //nolint:dupl
Expand Down Expand Up @@ -107,16 +154,18 @@ LD_LIBRARY_PATH=/usr/sap/S41/ASCS41/exe:$LD_LIBRARY_PATH; export LD_LIBRARY_PATH
Value: []entities.FactValue{
&entities.FactValueMap{
Value: map[string]entities.FactValue{
"sid": &entities.FactValueString{Value: "HS1"},
"kind": &entities.FactValueString{Value: "sapstartsrv"},
"content": &entities.FactValueString{Value: "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"},
"sid": &entities.FactValueString{Value: "HS1"},
"kind": &entities.FactValueString{Value: "sapstartsrv"},
"instance_nr": &entities.FactValueString{Value: "11"},
"content": &entities.FactValueString{Value: "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"},
},
},
&entities.FactValueMap{
Value: map[string]entities.FactValue{
"sid": &entities.FactValueString{Value: "S41"},
"kind": &entities.FactValueString{Value: "sapstartsrv"},
"content": &entities.FactValueString{Value: "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"},
"sid": &entities.FactValueString{Value: "S41"},
"kind": &entities.FactValueString{Value: "sapstartsrv"},
"instance_nr": &entities.FactValueString{Value: "41"},
"content": &entities.FactValueString{Value: "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"},
},
},
},
Expand Down Expand Up @@ -154,16 +203,68 @@ systemctl --no-ask-password start SAPS42_41
Value: []entities.FactValue{
&entities.FactValueMap{
Value: map[string]entities.FactValue{
"sid": &entities.FactValueString{Value: "S41"},
"kind": &entities.FactValueString{Value: "systemctl"},
"content": &entities.FactValueString{Value: "systemctl --no-ask-password start SAPS41_40"},
"sid": &entities.FactValueString{Value: "S41"},
"kind": &entities.FactValueString{Value: "systemctl"},
"instance_nr": &entities.FactValueString{Value: "40"},
"content": &entities.FactValueString{Value: "systemctl --no-ask-password start SAPS41_40"},
},
},
&entities.FactValueMap{
Value: map[string]entities.FactValue{
"sid": &entities.FactValueString{Value: "S42"},
"kind": &entities.FactValueString{Value: "systemctl"},
"instance_nr": &entities.FactValueString{Value: "41"},
"content": &entities.FactValueString{Value: "systemctl --no-ask-password start SAPS42_41"},
},
},
},
},
},
}
g := gatherers.NewSapServicesGatherer("/usr/sap/sapservices", tFs)
result, err := g.Gather(fr)
s.NoError(err)
s.EqualValues(expectedFacts, result)
}

func (s *SapServicesGathererSuite) TestSapServicesGathererSuccessWithAMiddleComment() { //nolint:dupl
tFs := afero.NewMemMapFs()
_ = afero.WriteFile(tFs, "/usr/sap/sapservices", []byte(`
#!/bin/sh
limit.descriptors=1048576
systemctl --no-ask-password start SAPHA1_10 # sapstartsrv pf=/usr/sap/HA1/SYS/profile/HA1_ERS10_sapha1er
systemctl --no-ask-password start SAPS42_41
`), 0777)

fr := []entities.FactRequest{
{
Name: "sapservices",
CheckID: "check1",
Gatherer: "sapservices",
},
}

expectedFacts := []entities.Fact{
{
Name: "sapservices",
CheckID: "check1",
Value: &entities.FactValueList{
Value: []entities.FactValue{
&entities.FactValueMap{
Value: map[string]entities.FactValue{
"sid": &entities.FactValueString{Value: "HA1"},
"kind": &entities.FactValueString{Value: "systemctl"},
"instance_nr": &entities.FactValueString{Value: "10"},

"content": &entities.FactValueString{Value: "systemctl --no-ask-password start SAPHA1_10 "},
},
},
&entities.FactValueMap{
Value: map[string]entities.FactValue{
"sid": &entities.FactValueString{Value: "S42"},
"kind": &entities.FactValueString{Value: "systemctl"},
"content": &entities.FactValueString{Value: "systemctl --no-ask-password start SAPS42_41"},
"sid": &entities.FactValueString{Value: "S42"},
"kind": &entities.FactValueString{Value: "systemctl"},
"instance_nr": &entities.FactValueString{Value: "41"},
"content": &entities.FactValueString{Value: "systemctl --no-ask-password start SAPS42_41"},
},
},
},
Expand Down
Loading