diff --git a/internal/factsengine/gatherers/osrelease.go b/internal/factsengine/gatherers/osrelease.go new file mode 100644 index 00000000..4eb18047 --- /dev/null +++ b/internal/factsengine/gatherers/osrelease.go @@ -0,0 +1,83 @@ +package gatherers + +import ( + "os" + + "github.com/hashicorp/go-envparse" + log "github.com/sirupsen/logrus" + "github.com/trento-project/agent/pkg/factsengine/entities" +) + +const ( + OSReleaseGathererName = "os-release" + OSReleaseFilePath = "/etc/os-release" +) + +// nolint:gochecknoglobals +var ( + OSReleaseFileError = entities.FactGatheringError{ + Type: "os-release-file-error", + Message: "error reading /etc/os-release file", + } + + OSReleaseDecodingError = entities.FactGatheringError{ + Type: "os-release-decoding-error", + Message: "error decoding file content", + } +) + +type OSReleaseGatherer struct { + osReleaseFilePath string +} + +func NewDefaultOSReleaseGatherer() *OSReleaseGatherer { + return NewOSReleaseGatherer(OSReleaseFilePath) +} + +func NewOSReleaseGatherer(path string) *OSReleaseGatherer { + return &OSReleaseGatherer{ + osReleaseFilePath: path, + } +} + +func (g *OSReleaseGatherer) Gather(factsRequests []entities.FactRequest) ([]entities.Fact, error) { + facts := []entities.Fact{} + log.Infof("Starting %s facts gathering process", OSReleaseGathererName) + + file, err := os.Open(g.osReleaseFilePath) + if err != nil { + log.Error(err) + return facts, OSReleaseFileError.Wrap(err.Error()) + } + defer file.Close() + + osRelease, err := envparse.Parse(file) + if err != nil { + log.Error(err) + return facts, OSReleaseDecodingError.Wrap(err.Error()) + } + + osReleaseFactValue := mapToFactValue(osRelease) + if err != nil { + log.Error(err) + return facts, OSReleaseDecodingError.Wrap(err.Error()) + } + + for _, requestedFact := range factsRequests { + fact := entities.NewFactGatheredWithRequest(requestedFact, osReleaseFactValue) + facts = append(facts, fact) + } + + log.Infof("Requested %s facts gathered", OSReleaseGathererName) + return facts, nil +} + +func mapToFactValue(inputMap map[string]string) entities.FactValue { + factValueMap := make(map[string]entities.FactValue) + + for key, value := range inputMap { + factValueMap[key] = &entities.FactValueString{Value: value} + } + + return &entities.FactValueMap{Value: factValueMap} +} diff --git a/internal/factsengine/gatherers/osrelease_test.go b/internal/factsengine/gatherers/osrelease_test.go new file mode 100644 index 00000000..435cdaf6 --- /dev/null +++ b/internal/factsengine/gatherers/osrelease_test.go @@ -0,0 +1,90 @@ +package gatherers_test + +import ( + "testing" + + "github.com/stretchr/testify/suite" + "github.com/trento-project/agent/internal/factsengine/gatherers" + "github.com/trento-project/agent/pkg/factsengine/entities" + "github.com/trento-project/agent/test/helpers" +) + +type OSReleaseGathererTestSuite struct { + suite.Suite +} + +func TestOSReleaseGathererTestSuite(t *testing.T) { + suite.Run(t, new(OSReleaseGathererTestSuite)) +} + +func (suite *OSReleaseGathererTestSuite) TestOSReleaseGathererSuccess() { + c := gatherers.NewOSReleaseGatherer(helpers.GetFixturePath("gatherers/os-release.basic")) + + factRequests := []entities.FactRequest{ + { + Name: "os-release", + Gatherer: "os-release@v1", + CheckID: "check1", + }, + } + + factResults, err := c.Gather(factRequests) + + expectedResults := []entities.Fact{ + { + Name: "os-release", + Value: &entities.FactValueMap{ + Value: map[string]entities.FactValue{ + "NAME": &entities.FactValueString{Value: "Ubuntu"}, + "VERSION": &entities.FactValueString{Value: "20.04.3 LTS (Focal Fossa)"}, + "ID": &entities.FactValueString{Value: "ubuntu"}, + "ID_LIKE": &entities.FactValueString{Value: "debian"}, + "VERSION_ID": &entities.FactValueString{Value: "20.04"}, + "PRETTY_NAME": &entities.FactValueString{Value: "Ubuntu 20.04.3 LTS"}, + "VERSION_CODENAME": &entities.FactValueString{Value: "focal"}, + "HOME_URL": &entities.FactValueString{Value: "https://www.ubuntu.com/"}, + "SUPPORT_URL": &entities.FactValueString{Value: "https://help.ubuntu.com/"}, + "BUG_REPORT_URL": &entities.FactValueString{Value: "https://bugs.launchpad.net/ubuntu/"}, + "PRIVACY_POLICY_URL": &entities.FactValueString{Value: "https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"}, + "UBUNTU_CODENAME": &entities.FactValueString{Value: "focal"}, + }, + }, + CheckID: "check1", + }, + } + + suite.NoError(err) + suite.ElementsMatch(expectedResults, factResults) +} + +func (suite *OSReleaseGathererTestSuite) TestOSReleaseGathererFileNotExists() { + c := gatherers.NewOSReleaseGatherer("non_existing_file") + + factRequests := []entities.FactRequest{ + { + Name: "os-release", + Gatherer: "os-release@v1", + }, + } + + _, err := c.Gather(factRequests) + + suite.EqualError(err, "fact gathering error: os-release-file-error - error reading /etc/os-release file: "+ + "open non_existing_file: no such file or directory") +} + +func (suite *OSReleaseGathererTestSuite) TestOSReleaseGathererErrorDecoding() { + + c := gatherers.NewOSReleaseGatherer(helpers.GetFixturePath("gatherers/os-release.invalid")) + + factRequests := []entities.FactRequest{ + { + Name: "os-release", + Gatherer: "os-release", + }, + } + + _, err := c.Gather(factRequests) + + suite.EqualError(err, "fact gathering error: os-release-decoding-error - error decoding file content: error on line 3: missing =") +} diff --git a/test/fixtures/gatherers/os-release.basic b/test/fixtures/gatherers/os-release.basic new file mode 100644 index 00000000..dadd892a --- /dev/null +++ b/test/fixtures/gatherers/os-release.basic @@ -0,0 +1,12 @@ +NAME="Ubuntu" +VERSION="20.04.3 LTS (Focal Fossa)" +ID=ubuntu +ID_LIKE=debian +VERSION_ID="20.04" +PRETTY_NAME="Ubuntu 20.04.3 LTS" +VERSION_CODENAME=focal +HOME_URL="https://www.ubuntu.com/" +SUPPORT_URL="https://help.ubuntu.com/" +BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/" +PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" +UBUNTU_CODENAME=focal diff --git a/test/fixtures/gatherers/os-release.invalid b/test/fixtures/gatherers/os-release.invalid new file mode 100644 index 00000000..f7901bce --- /dev/null +++ b/test/fixtures/gatherers/os-release.invalid @@ -0,0 +1,3 @@ +NAME="Ubuntu" +VERSION="20.04.3 LTS (Focal Fossa)" +ID_ubuntu