Skip to content

Conversation

@DsgnrFH
Copy link
Collaborator

@DsgnrFH DsgnrFH commented Oct 31, 2025

Moved the netgear related things to a netgear package
Resolves #3

@DsgnrFH DsgnrFH requested review from oxzi and yhabteab October 31, 2025 14:06
@DsgnrFH DsgnrFH self-assigned this Oct 31, 2025
@DsgnrFH DsgnrFH added the enhancement New feature or request label Oct 31, 2025
@cla-bot
Copy link

cla-bot bot commented Oct 31, 2025

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

  • If you've already signed a CLA, it's possible we don't have your GitHub username or you're using a different email address. Please contact us if you think this is the case.

  • If you signed the CLA as a corporation, your GitHub username may not have been submitted to us. Please reach out to the responsible person in your organization.

@DsgnrFH
Copy link
Collaborator Author

DsgnrFH commented Oct 31, 2025

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

* If you've already signed a CLA, it's possible we don't have your GitHub username or you're using a different email address. Please [contact us](https://icinga.com/company/contact/) if you think this is the case.

* If you signed the CLA as a corporation, your GitHub username may not have been submitted to us. Please reach out to the responsible person in your organization.

test1

@DsgnrFH
Copy link
Collaborator Author

DsgnrFH commented Oct 31, 2025

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

with a comment

@bobapple
Copy link
Member

@cla-bot check

@cla-bot cla-bot bot added the cla/signed CLA is signed by all contributors of a PR label Oct 31, 2025
Copy link
Member

@oxzi oxzi left a 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.

func NewNetgear(hostName, username, password string) *Netgear {
return &Netgear{
client: &http.Client{Timeout: timeout},
hostName: strings.TrimSuffix(hostName, "/") + "/api/v1",
Copy link
Member

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.

Comment on lines 63 to 71
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)
}
Copy link
Member

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.


userRaw, ok := result["user"]
if !ok {
return fmt.Errorf("login response: missing 'user' field; body: %s", string(body))
Copy link
Member

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.


req, err := http.NewRequest(
http.MethodPost,
fmt.Sprintf("%s/login", n.hostName),
Copy link
Member

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.

return err
}
defer func() { _ = resp.Body.Close() }()
_, _ = io.ReadAll(resp.Body) // body ignored intentionally
Copy link
Member

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.

Suggested change
_, _ = 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)
Copy link
Member

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
Comment on lines 63 to 72
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))
}
Copy link
Member

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 {
Copy link
Member

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
Comment on lines 28 to 36
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")
Copy link
Member

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
}

Copy link
Member

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.

@DsgnrFH DsgnrFH requested a review from oxzi November 3, 2025 09:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla/signed CLA is signed by all contributors of a PR enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Move all the netgear related things to a separate package

4 participants