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

feat(product): Add 'product' commands for each Fastly product. #1362

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

kpfleming
Copy link
Contributor

Adds 'enable', 'disable', and 'status' commands for each product previously supported by the 'products' command (which is now deprecated).

Also adds 'configure' commands for products which support configuration (DDoS Protection and Next-Gen WAF).

Adds 'enable', 'disable', and 'status' commands for each product
previously supported by the 'products' command (which is now
deprecated).

Also adds 'configure' commands for products which support
configuration (DDoS Protection and Next-Gen WAF).
@kpfleming kpfleming added DO NOT MERGE YET dependencies Pull requests that update a dependency file labels Dec 17, 2024
Copy link
Contributor

@cee-dub cee-dub left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love the test mocking. Package names could be more idiomatic.

Comment on lines +82 to +111
_, err = GetFn(c.Globals.APIClient, serviceID)
if err != nil {
var herr *fastly.HTTPError

// The API returns a 'Bad Request' error when the
// product has not been enabled on the service; any
// other error should be reported
if !errors.As(err, &herr) || !herr.IsBadRequest() {
c.Globals.ErrLog.Add(err)
return err
}
} else {
s.Enabled = true
}

if ok, err := c.WriteJSON(out, s); ok {
return err
}

var msg string
if s.Enabled {
msg = "enabled"
} else {
msg = "disabled"
}

text.Info(out,
bot_management.ProductName+" is %s on service %s", msg, serviceID)

return nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logic is a bit hard to follow. One idea...

Suggested change
_, err = GetFn(c.Globals.APIClient, serviceID)
if err != nil {
var herr *fastly.HTTPError
// The API returns a 'Bad Request' error when the
// product has not been enabled on the service; any
// other error should be reported
if !errors.As(err, &herr) || !herr.IsBadRequest() {
c.Globals.ErrLog.Add(err)
return err
}
} else {
s.Enabled = true
}
if ok, err := c.WriteJSON(out, s); ok {
return err
}
var msg string
if s.Enabled {
msg = "enabled"
} else {
msg = "disabled"
}
text.Info(out,
bot_management.ProductName+" is %s on service %s", msg, serviceID)
return nil
state := "disabled"
_, err = GetFn(c.Globals.APIClient, serviceID)
if err != nil {
// The API returns a 'Bad Request' error when the product has
// not been enabled on the service so we ignore it; any other
// error should be reported
var herr *fastly.HTTPError
if !errors.As(err, &herr) || !herr.IsBadRequest() {
c.Globals.ErrLog.Add(err)
return err
}
} else {
s.Enabled = true
state = "enabled"
}
if ok, err := c.WriteJSON(out, s); ok {
return err
}
text.Info(out, bot_management.ProductName+" is %s on service %s", state, serviceID)
return nil

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh, yes, that's definitely better. I'll roll this into some other changes in the branch.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I didn't use my normal editor and looks like I have a syntax error in there.

@@ -0,0 +1,112 @@
package bot_management
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The linter is agreeing with me that package names shouldn't have underscores.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah... I've been trying to stick with using our actual product IDs for ease of understanding by future maintainers, but the Go community has a different opinion (except for test packages, where underscores are allowed).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case it is representing a build tag. The same works for other specific words that match OS targets or architectures, like _linux or _arm64.

Copy link
Contributor

@cee-dub cee-dub Dec 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's also the only exception to two packages existing in one directory, where p and p_test can coexist to allow for blackbox testing of p.

Globals: g,
},
}
c.CmdClause = parent.Command("disable", "Disable the "+bot_management.ProductName+" product")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At first, I was rather confused until I realized that bot_management.ProductName refers to github.com/fastly/go-fastly/v9/fastly/products/bot_management.ProductName and not to something in this package. Same for the rest of the bot_management.Things in pkg/commands/product/bot_management/*.go files.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was confused by that when I started working in Go; if you're in package A, and you've also imported a package named A, then qualified references like A.foo always refer to the imported package and never to the 'local' package. Now that I've gotten used to it I'm not bothered by it, but this sort of thing is what prompted the desire for import aliases in the other project :-)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might I suggest an alias is probably appropriate here? bot or botapi could work

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is what got me down the road of using a 'generic' import alias in the other project; if there are 9 packages that all import their corresponding 'API' functionality from another module, they could use the same import alias, to keep things consistent for the reader.

What crosses my mind is that if I see bot.ProductName and ddos.ProductName I might think that those are different in some way, but if they are both api.ProductName I'll know right away that they represent the same concept. Granted, calling it <anything>.ProductName should also be sufficient to express the concept...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try it and see what feels best, I guess!


// DisableFn is a dependency-injection point for unit tests to provide
// a mock implementation of the API operation.
var DisableFn = func(client api.Interface, serviceID string) error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably a Go idiom or just a style preference of my own from familiarity with the standard library, but i suggest DisableFunc and friends.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
dependencies Pull requests that update a dependency file DO NOT MERGE YET
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants