diff --git a/.gitignore b/.gitignore index c177d61..4632894 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,8 @@ dist/ check_sentinelone .env* +.vscode/ +launch.json coverage.html coverage.out \ No newline at end of file diff --git a/api/response.go b/api/response.go index 629b6ee..7e32655 100644 --- a/api/response.go +++ b/api/response.go @@ -40,6 +40,7 @@ type JSONError struct { func (c *Client) GetJSONResponse(req *http.Request) (data *ResponseBody, err error) { res, err := c.Do(req) + if err != nil { return } diff --git a/api/threats.go b/api/threats.go index 47aba2c..f1a1610 100644 --- a/api/threats.go +++ b/api/threats.go @@ -9,6 +9,7 @@ import ( type Threat struct { AgentRealtimeInfo AgentRealtimeInfo `json:"agentRealtimeInfo"` ThreatInfo ThreatInfo `json:"threatInfo"` + KubernetesInfo KubernetesInfo `json:"kubernetesInfo"` } type AgentRealtimeInfo struct { @@ -22,6 +23,10 @@ type AgentRealtimeInfo struct { AgentDomain string `json:"AgentDomain"` } +type KubernetesInfo struct { + Cluster string `json:"cluster"` +} + type ThreatInfo struct { ThreatName string `json:"threatName"` Classification string `json:"classification"` @@ -36,7 +41,7 @@ type ThreatInfo struct { MitigationStatusDescription string `json:"mitigationStatusDescription"` } -func (c *Client) GetThreats(values url.Values) (threats []*Threat, err error) { +func (c *Client) GetThreats(values url.Values, computername string, groupID string, groupName string, cluster string) (threats []*Threat, err error) { // nolint: noctx req, err := c.NewRequest("GET", "v2.1/threats?"+values.Encode(), nil) if err != nil { @@ -55,6 +60,15 @@ func (c *Client) GetThreats(values url.Values) (threats []*Threat, err error) { if err != nil { return } + if computername != "" && computername != t.AgentRealtimeInfo.AgentComputerName { + continue + } else if groupID != "" && groupID != t.AgentRealtimeInfo.GroupID { + continue + } else if groupName != "" && groupName != t.AgentRealtimeInfo.GroupName { + continue + } else if cluster != "" && cluster != t.KubernetesInfo.Cluster { + continue + } threats = append(threats, t) } diff --git a/check.go b/check.go index 934d947..4f398dc 100644 --- a/check.go +++ b/check.go @@ -18,6 +18,9 @@ type Config struct { IgnoreInProgress bool SiteName string ComputerName string + GroupID string + GroupName string + Cluster string } func BuildConfigFlags(fs *pflag.FlagSet) (config *Config) { @@ -26,14 +29,14 @@ func BuildConfigFlags(fs *pflag.FlagSet) (config *Config) { fs.StringVarP(&config.ManagementURL, "url", "H", "", "Management URL (e.g. https://your-site.sentinelone.net) (env:SENTINELONE_URL)") fs.StringVarP(&config.AuthToken, "token", "T", "", "API AuthToken (env:SENTINELONE_TOKEN)") - fs.StringVar(&config.SiteName, "site", "", "Only list threats belonging to a named site") - fs.BoolVar(&config.IgnoreInProgress, "ignore-in-progress", false, "Ignore threats, where the incident status is in-progress") - fs.StringVar(&config.ComputerName, "computer-name", "", "Only list threats belonging to the specified computer name") + fs.StringVar(&config.GroupID, "group-id", "", "List threats belonging to the specified groupID") + fs.StringVar(&config.GroupName, "group-name", "", "List threats belonging to the specified group name") + fs.StringVar(&config.Cluster, "cluster", "", "List threats belonging to one k8s cluster") return } @@ -83,7 +86,7 @@ func (c *Config) Run() (rc int, output string, err error) { values.Set("computerName__contains", c.ComputerName) } - threats, err := client.GetThreats(values) + threats, err := client.GetThreats(values, c.ComputerName, c.GroupID, c.GroupName, c.Cluster) if err != nil { return } @@ -121,7 +124,6 @@ func (c *Config) Run() (rc int, output string, err error) { if threat.ThreatInfo.MitigationStatus == "not_mitigated" { notMitigated++ - stateText = "CRITICAL" } else { stateText = "WARNING" @@ -146,6 +148,10 @@ func (c *Config) Run() (rc int, output string, err error) { sb.WriteString(fmt.Sprintf("site %s - ", c.SiteName) + sb.String()) } else if c.ComputerName != "" { sb.WriteString(fmt.Sprintf("Computer %s - ", c.ComputerName) + sb.String()) + } else if c.GroupID != "" { + sb.WriteString(fmt.Sprintf("Group %s - ", c.GroupID) + sb.String()) + } else if c.Cluster != "" { + sb.WriteString(fmt.Sprintf("Cluster %s - ", c.Cluster) + sb.String()) } // Add perfdata. diff --git a/go.mod b/go.mod index 87099d9..49d7453 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,8 @@ module github.com/NETWAYS/check_sentinelone -go 1.22 +go 1.22.0 + +toolchain go1.22.1 require ( github.com/NETWAYS/go-check v0.6.2 @@ -12,6 +14,7 @@ require ( require ( github.com/davecgh/go-spew v1.1.1 // indirect + github.com/google/go-cmp v0.6.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 1b6d964..2d3250b 100644 --- a/go.sum +++ b/go.sum @@ -3,8 +3,8 @@ github.com/NETWAYS/go-check v0.6.2/go.mod h1:qx8m3s2Xul9wqfUjrCSArEFkOdtwxIyUmBY github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/jarcoal/httpmock v1.3.1 h1:iUx3whfZWVf3jT01hQTO/Eo5sAYtB2/rqaUuOtpInww= github.com/jarcoal/httpmock v1.3.1/go.mod h1:3yb8rc4BI7TCBhFY8ng0gjuLKJNquuDNiPaZjnENuYg= github.com/maxatome/go-testdeep v1.12.0 h1:Ql7Go8Tg0C1D/uMMX59LAoYK7LffeJQ6X2T04nTH68g=