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

improve the host OS collector and analyzer #1743

Merged
merged 5 commits into from
Feb 20, 2025
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
10 changes: 5 additions & 5 deletions examples/sdk/helm-template/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,14 @@ require (
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/api v0.32.1 // indirect
k8s.io/apiextensions-apiserver v0.32.1 // indirect
k8s.io/apimachinery v0.32.1 // indirect
k8s.io/client-go v0.32.1 // indirect
k8s.io/api v0.32.2 // indirect
k8s.io/apiextensions-apiserver v0.32.2 // indirect
k8s.io/apimachinery v0.32.2 // indirect
k8s.io/client-go v0.32.2 // indirect
k8s.io/klog/v2 v2.130.1 // indirect
k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f // indirect
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect
sigs.k8s.io/controller-runtime v0.20.1 // indirect
sigs.k8s.io/controller-runtime v0.20.2 // indirect
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.2 // indirect
)
5 changes: 5 additions & 0 deletions examples/sdk/helm-template/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -165,12 +165,16 @@ helm.sh/helm/v3 v3.17.1 h1:gzVoAD+qVuoJU6KDMSAeo0xRJ6N1znRxz3wyuXRmJDk=
helm.sh/helm/v3 v3.17.1/go.mod h1:nvreuhuR+j78NkQcLC3TYoprCKStLyw5P4T7E5itv2w=
k8s.io/api v0.32.1 h1:f562zw9cy+GvXzXf0CKlVQ7yHJVYzLfL6JAS4kOAaOc=
k8s.io/api v0.32.1/go.mod h1:/Yi/BqkuueW1BgpoePYBRdDYfjPF5sgTr5+YqDZra5k=
k8s.io/api v0.32.2/go.mod h1:hKlhk4x1sJyYnHENsrdCWw31FEmCijNGPJO5WzHiJ6Y=
k8s.io/apiextensions-apiserver v0.32.1 h1:hjkALhRUeCariC8DiVmb5jj0VjIc1N0DREP32+6UXZw=
k8s.io/apiextensions-apiserver v0.32.1/go.mod h1:sxWIGuGiYov7Io1fAS2X06NjMIk5CbRHc2StSmbaQto=
k8s.io/apiextensions-apiserver v0.32.2/go.mod h1:GPwf8sph7YlJT3H6aKUWtd0E+oyShk/YHWQHf/OOgCA=
k8s.io/apimachinery v0.32.1 h1:683ENpaCBjma4CYqsmZyhEzrGz6cjn1MY/X2jB2hkZs=
k8s.io/apimachinery v0.32.1/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE=
k8s.io/apimachinery v0.32.2/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE=
k8s.io/client-go v0.32.1 h1:otM0AxdhdBIaQh7l1Q0jQpmo7WOFIk5FFa4bg6YMdUU=
k8s.io/client-go v0.32.1/go.mod h1:aTTKZY7MdxUaJ/KiUs8D+GssR9zJZi77ZqtzcGXIiDg=
k8s.io/client-go v0.32.2/go.mod h1:fpZ4oJXclZ3r2nDOv+Ux3XcJutfrwjKTCHz2H3sww94=
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f h1:GA7//TjRY9yWGy1poLzYYJJ4JRdzg3+O6e8I+e+8T5Y=
Expand All @@ -179,6 +183,7 @@ k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6J
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
sigs.k8s.io/controller-runtime v0.20.1 h1:JbGMAG/X94NeM3xvjenVUaBjy6Ui4Ogd/J5ZtjZnHaE=
sigs.k8s.io/controller-runtime v0.20.1/go.mod h1:BrP3w158MwvB3ZbNpaAcIKkHQ7YGpYnzpoSTZ8E14WU=
sigs.k8s.io/controller-runtime v0.20.2/go.mod h1:xg2XB0K5ShQzAgsoujxuKN4LNXR2LfwwHsPj7Iaw+XY=
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8=
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo=
sigs.k8s.io/structured-merge-diff/v4 v4.4.2 h1:MdmvkGuXi/8io6ixD5wud3vOLwc1rj0aNqRlpuvjmwA=
Expand Down
39 changes: 36 additions & 3 deletions pkg/analyze/host_os_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,46 @@ func (a *AnalyzeHostOS) CheckCondition(when string, data []byte) (bool, error) {
if len(parts) < 3 {
return false, errors.New("when condition must have at least 3 parts")
}

// handle things like "ubuntu == 20.04", but also "ubuntu == 20.04 || < 20.04" or "ubuntu == 20.04 || < 20.04 || >= 20.04" etc
// the number of parts should be a multiple of 3
if len(parts)%3 != 0 {
return false, errors.New("when condition must have a multiple of 3 parts, such as 'ubuntu == 20.04' or 'rhel >= 8 && < 9'")
}

stringToParse := ""
expectedVer := fixVersion(parts[2])
toleratedVer, err := semver.ParseTolerant(expectedVer)
if err != nil {
return false, errors.Wrapf(err, "failed to parse version: %s", expectedVer)
}
when = fmt.Sprintf("%s %v", parts[1], toleratedVer)
whenRange, err := semver.ParseRange(when)
stringToParse = fmt.Sprintf("%s %s", parts[1], toleratedVer.String())

trimmedParts := strings.Split(when, " ")
// read through the next three parts if they exist - this could look like "|| < 20.04" or "&& >= 8"
for len(trimmedParts) > 3 {
trimmedParts = trimmedParts[3:]

expectedVer = fixVersion(trimmedParts[2])
toleratedVer, err = semver.ParseTolerant(expectedVer)
if err != nil {
return false, errors.Wrapf(err, "failed to parse version: %s", expectedVer)
}

// first part is either "||" or "&&"
// if it's "&&", it is assumed by the semver package and should not be included
// second part is the conditional
// third part is the version
if trimmedParts[0] == "||" {
stringToParse = fmt.Sprintf("%s %s %s %s", stringToParse, trimmedParts[0], trimmedParts[1], toleratedVer.String())
} else if trimmedParts[0] == "&&" {
stringToParse = fmt.Sprintf("%s %s %s", stringToParse, trimmedParts[1], toleratedVer.String())
} else {
return false, errors.Errorf("invalid conditional, expected either && or ||, got %q", trimmedParts[0])
}
}

whenRange, err := semver.ParseRange(stringToParse)
if err != nil {
return false, errors.Wrapf(err, "failed to parse version range: %s", when)
}
Expand Down Expand Up @@ -97,7 +130,7 @@ func (a *AnalyzeHostOS) CheckCondition(when string, data []byte) (bool, error) {
return true, nil
}
}
} else if platform == osInfo.Platform {
} else if platform == osInfo.Platform || platform == osInfo.PlatformFamily {
fixedDistVer := fixVersion(osInfo.PlatformVersion)
toleratedDistVer, err := semver.ParseTolerant(fixedDistVer)
if err != nil {
Expand Down
91 changes: 91 additions & 0 deletions pkg/analyze/host_os_info_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,47 @@ func TestAnalyzeHostOSCheckCondition(t *testing.T) {
expected: true,
expectErr: false,
},
{
name: "centos < 8 when actual is 7.2",
conditional: "centos < 8",
osInfo: collect.HostOSInfo{
Platform: "centos",
PlatformVersion: "7.2",
},
expected: true,
expectErr: false,
},
{
name: "centos < 8 when actual is 8.2",
conditional: "centos < 8",
osInfo: collect.HostOSInfo{
Platform: "centos",
PlatformVersion: "8.2",
},
expected: false,
expectErr: false,
},
{
name: "centos < 8 when actual is rhel 7.2", // this tests that we properly exclude other OSes despite the version matching
conditional: "centos < 8",
osInfo: collect.HostOSInfo{
Platform: "redhat",
PlatformVersion: "7.2",
},
expected: false,
expectErr: false,
},
{
name: "rhel == 8.2 when actual is 8.2", // this tests that we match on either platform or platform family
conditional: "rhel == 8.2",
osInfo: collect.HostOSInfo{
Platform: "centos",
PlatformFamily: "rhel",
PlatformVersion: "8.2",
},
expected: true,
expectErr: false,
},
{
name: "ubuntu == 20.04 when actual is 18.04",
conditional: "ubuntu == 20.04",
Expand All @@ -69,6 +110,56 @@ func TestAnalyzeHostOSCheckCondition(t *testing.T) {
expected: false,
expectErr: true,
},
{
name: "multiple conditionals, neither true",
conditional: "ubuntu > 20.04 || <= 18.04",
osInfo: collect.HostOSInfo{
Platform: "ubuntu",
PlatformVersion: "20.04",
},
expected: false,
expectErr: false,
},
{
name: "multiple conditionals, first true",
conditional: "ubuntu > 20.04 || <= 18.04",
osInfo: collect.HostOSInfo{
Platform: "ubuntu",
PlatformVersion: "22.04",
},
expected: true,
expectErr: false,
},
{
name: "multiple conditionals, second true",
conditional: "ubuntu > 20.04 || <= 18.04",
osInfo: collect.HostOSInfo{
Platform: "ubuntu",
PlatformVersion: "18.04",
},
expected: true,
expectErr: false,
},
{
name: "multiple conditionals, between the two",
conditional: "redhat >= 8 && < 9",
osInfo: collect.HostOSInfo{
Platform: "redhat",
PlatformVersion: "8.2",
},
expected: true,
expectErr: false,
},
{
name: "multiple conditionals, outside the two",
conditional: "redhat >= 8 && < 9",
osInfo: collect.HostOSInfo{
Platform: "redhat",
PlatformVersion: "9.2",
},
expected: false,
expectErr: false,
},
}

for _, test := range tests {
Expand Down
2 changes: 2 additions & 0 deletions pkg/collect/host_os_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ type HostOSInfo struct {
KernelVersion string `json:"kernelVersion"`
PlatformVersion string `json:"platformVersion"`
Platform string `json:"platform"`
PlatformFamily string `json:"platformFamily"`
}

type HostOSInfoNodes struct {
Expand Down Expand Up @@ -44,6 +45,7 @@ func (c *CollectHostOS) Collect(progressChan chan<- interface{}) (map[string][]b
}
hostInfo := HostOSInfo{}
hostInfo.Platform = infoStat.Platform
hostInfo.PlatformFamily = infoStat.PlatformFamily
hostInfo.KernelVersion = infoStat.KernelVersion
hostInfo.Name = infoStat.Hostname
hostInfo.PlatformVersion = infoStat.PlatformVersion
Expand Down
5 changes: 3 additions & 2 deletions pkg/collect/host_os_info_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@ func TestCollectHostOS_Collect(t *testing.T) {
require.NoError(t, err)

// Check if values exist. They will be different on different machines.
assert.Equal(t, 4, len(m))
assert.Equal(t, 5, len(m))
assert.Contains(t, m, "name")
assert.Contains(t, m, "kernelVersion")
assert.Contains(t, m, "platformVersion")
assert.Contains(t, m, "platformVersion")
assert.Contains(t, m, "platform")
assert.Contains(t, m, "platformFamily")
}
Loading