-
Notifications
You must be signed in to change notification settings - Fork 1
Restructured the whole code #4
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
base: main
Are you sure you want to change the base?
Conversation
|
Thank you for your pull request. Before we can look at it, you'll need to sign a Contributor License Agreement (CLA). Please follow instructions at https://icinga.com/company/contributor-agreement to sign the CLA. After that, please reply here with a comment and we'll verify. Contributors that have not signed yet: @DsgnrFH
|
test1 |
with a comment |
|
@cla-bot check |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First, thanks for creating this PR. I have skimmed over the code and made some first comments.
netgear/netgear.go
Outdated
| func NewNetgear(hostName, username, password string) *Netgear { | ||
| return &Netgear{ | ||
| client: &http.Client{Timeout: timeout}, | ||
| hostName: strings.TrimSuffix(hostName, "/") + "/api/v1", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider using URL.JoinPath when constructing URLs.
Furthermore, Netgear.hostName is used as an URL throughout the code, thus consider changing its type to url.URL. And while doing so, consider renaming the variable since it carries an URL and not only a host name.
netgear/netgear.go
Outdated
| body, err := io.ReadAll(resp.Body) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| var result map[string]any | ||
| if err := json.Unmarshal(body, &result); err != nil { | ||
| return fmt.Errorf("failed to parse login response JSON: %w", err) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of reading the whole body (of unknown size!) into a buffer, just to read the whole content afterwards, consider using the response body as an io.Reader. You can feed the .Body directly into json.NewDecoder.
netgear/netgear.go
Outdated
|
|
||
| userRaw, ok := result["user"] | ||
| if !ok { | ||
| return fmt.Errorf("login response: missing 'user' field; body: %s", string(body)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would advise against including the actually response body into an error message. For one, you cannot know how big the body is - potentially ending up with a huuuuge error. Furthermore, it may contain sensitive information.
netgear/netgear.go
Outdated
|
|
||
| req, err := http.NewRequest( | ||
| http.MethodPost, | ||
| fmt.Sprintf("%s/login", n.hostName), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By changing Netgear.hostName to an url.URL as suggested above, you can just use .JoinPath for these URL constructions.
netgear/netgear.go
Outdated
| return err | ||
| } | ||
| defer func() { _ = resp.Body.Close() }() | ||
| _, _ = io.ReadAll(resp.Body) // body ignored intentionally |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even if ignoring the return value, this would allocate a buffer and fill it once, just to be collected by the garbage collection later on. Instead of reading data into a buffer, consider streaming it into the void, io.Discard.
| _, _ = io.ReadAll(resp.Body) // body ignored intentionally | |
| _, _ = io.Copy(io.Discard, resp.Body) |
| if err != nil { // Error is present, display it | ||
| n := netgear.NewNetgear(*hostName, *username, *password) | ||
| if err := n.Login(); err != nil { | ||
| fmt.Printf("Error while trying to login: %v\n", err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When the check plugin fails to login, it just exits with exit code 0 - thus, OK. This should be an UNKNOWN.
main.go
Outdated
| var deviceInfo netgear.DeviceInfo | ||
| inputData, err := n.DeviceInfo() | ||
| if err != nil { | ||
| panic(err) | ||
| fmt.Printf("Error retrieving device info: %v\n", err) | ||
| os.Exit(int(check.Unknown)) | ||
| } | ||
| if err := json.Unmarshal(inputData, &deviceInfo); err != nil { | ||
| fmt.Printf("Failed to parse JSON: %v\n", err) | ||
| os.Exit(int(check.Unknown)) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I mentioned in the library, the caller should not do the conversion from some magic byte slice to a type, but this should happen in the library. Afterwards, this code would look way cleaner.
|
|
||
| // CPU check | ||
| // CPU | ||
| if !*hidecpu { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All these checks - CPU, Memory, Temperature, and so on - could be extracted into their own function, which is then just called here. This would help making the main function more readable. Furthermore, this might show repeated patterns for a further refactoring.
main.go
Outdated
| CPU_WARN := pflag.Float64("cpu-warning", 50, "CPU usage warning threshold") | ||
| CPU_CRIT := pflag.Float64("cpu-critical", 90, "CPU usage critical threshold") | ||
| MEM_WARN := pflag.Float64("mem-warning", 50, "RAM usage warning threshold") | ||
| MEM_CRIT := pflag.Float64("mem-critical", 90, "RAM usage critical threshold") | ||
| FAN_WARN := pflag.Float64("fan-warning", 3000, "Fan speed warning threshold") | ||
| TEMP_WARN := pflag.Float64("temp-warning", 50, "Temperature warning threshold") | ||
| TEMP_CRIT := pflag.Float64("temp-critical", 70, "Temperature critical threshold") | ||
| STATS_WARN := pflag.Float64("stats-warning", 5, "Port stats warning threshold") | ||
| STATS_CRIT := pflag.Float64("stats-critical", 20, "Port stats critical threshold") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Usually, variables in Go are not written in ALL CAPS nor in snake_case. Something like flagCpuWarn, flagCpuCrit, … would be more idiomatic.
main.go
Outdated
| } | ||
| return a | ||
| } | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a generic max function in the Go builtins.
… & remove custom maxStatus
Moved the netgear related things to a netgear package
Resolves #3