-
Notifications
You must be signed in to change notification settings - Fork 27
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
Added the default ignore config for service disable error #476
base: main
Are you sure you want to change the base?
Conversation
@johnsmyth I think this feature is helpful for ignoring errors better, especially when the error codes we get back are simple and lack details, e.g., One thought I had was, would more flexibility in be helpful or too complex? For instance:
The main use case would be ignoring specific code/message combinations, e.g., if multiple error codes had similar messages, but typing it out, it seems a little more complex than required in this case and in most plugins. |
@cbruno10 You are correct that |
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.
@ParthaI Please see review comments, thanks!
config/gcp.spc
Outdated
@@ -20,6 +20,9 @@ connection "gcp" { | |||
# If not set, no impersonation is done. | |||
#impersonate_service_account = "YOUR_SERVICE_ACCOUNT" | |||
|
|||
# `ignore_error_messages` (optional) - List of additional GCP error message pattern to ignore for all queries. | |||
# ignore_error_messages = ["API has not been used", "other regex"] |
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.
@ParthaI Is there a more exact regex (using ^
, $
) we should add as an example here, in particular for the "API has not been used" case? We can probably remove other regex
as it's not helpful.
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.
This is a really good addition to handle cases where, google uses the same 403 error code when - API are not enabled and when Quota exceeded. An exact regex mapping example to an error message would sure be helpful.
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.
For reference, this is reported as this:
ERROR: googleapi: Error 403: Cloud DNS API has not been used in project XXX before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/dns.go…
Details:
[
{
"@type": "type.googleapis.com/google.rpc.Help",
"links": [
{
"description": "Google developers console API activation",
"url": "https://console.developers.google.com/apis/api/dns.googleapis.com/overview?project=XXX"
}
]
},
{
"@type": "type.googleapis.com/google.rpc.ErrorInfo",
"domain": "googleapis.com",
"metadata": {
"consumer": "projects/XXX",
"service": "dns.googleapis.com"
},
"reason": "SERVICE_DISABLED"
}
]
, accessNotConfigured (SQLSTATE HV000)
So I think the current example with API has not been used
would be enough.
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.
@cbruno10, I have added the example for the exact regex (using ^, $) i.e ignore_error_messages = ["^.*API\\s*has\\s*not\\s*been\\s*used.*$"]
. Also we can pass a message just like a string format, in both of the case the code changes are working fine.
NOTE: In the .spc file, we should use \\
instead of \
for the regex pattern to avoid errors related to escape characters. Otherwise, parsing the .spc file might result in an error like "Invalid escape sequence: The symbol "d" is not a valid escape sequence selector."
gcp/ignore_error_predicate.go
Outdated
if gerr, ok := err.(*googleapi.Error); ok { | ||
for _, pattern := range gcpConfig.IgnoreErrorMessages { | ||
re := regexp.MustCompile(pattern) | ||
result := re.FindString(types.ToString(gerr.Message)) |
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.
Does GCP ever send messages that don't have the Message
property? If so, does this code still handle everything ok?
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 haven't encountered any errors without a message property. Additionally, we are converting errors of type googleapi.Error
, which always includes a message property. I've tested it multiple times with various connection combinations, and it's working correctly, handling errors as expected.
If an error does not contain a message
property, the code block above will not function as it is designed to handle errors based on their error message. In cases where the message
property is not available, an alternative approach is to configure the ignore_error_codes
in the .spc file. This will allow the following line of code to handle the error.
According to the GCP API design documentation, errors include a message property. However, it's important to note that Error messages are not part of the API surface. They are subject to changes without notice. Application code should not rely heavily on error messages as they may change.
gcp/ignore_error_predicate.go
Outdated
if gerr, ok := err.(*googleapi.Error); ok { | ||
for _, pattern := range gcpConfig.IgnoreErrorMessages { | ||
re := regexp.MustCompile(pattern) | ||
result := re.FindString(types.ToString(gerr.Message)) |
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.
Does this function support matching on full regular expressions? How is this different than the regex Match
function?
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.
Yes, this function support matching on full regular expressions.
-
*func (re Regexp) FindString(s string) string
FindString returns a string holding the text of the leftmost match in s of the regular expression. If there is no match, the return value is an empty string, but it will also be empty if the regular expression successfully matches an empty string. Use FindStringIndex or FindStringSubmatch if it is necessary to distinguish these cases. -
*func (re Regexp) Match(b []byte) bool
Match reports whether the byte slice b contains any match of the regular expression re.
IMO, it would be better to use MatchString
function here. I can see in most of the place we use MatchString
function to validate patterns. https://github.com/search?q=repo%3Aturbot%2Fsteampipe%20MatchString&type=code
I have replace the function FindString
to MatchString
.
gcp/ignore_error_predicate.go
Outdated
} | ||
} | ||
|
||
if !hasIgnoredErrorCodes(d.Connection) { |
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.
Do we need this block still?
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.
Removed this block of code as we do not need those.
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.
@ParthaI Please see comments, thanks!
@@ -20,6 +20,9 @@ connection "gcp" { | |||
# If not set, no impersonation is done. | |||
#impersonate_service_account = "YOUR_SERVICE_ACCOUNT" | |||
|
|||
# `ignore_error_messages` (optional) - List of additional GCP error message pattern to ignore for all queries. | |||
# ignore_error_messages = ["^.*API has not been used.*$"] |
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.
What error does a user receive if an invalid regex is passed in?
Also, do users need to use ^
and $
, or will we still match without those explicitly included in a pattern?
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.
The user will receive an error error parsing regexp: invalid escape sequence:
during the query execution if a user provide an invalid regex.
User may include ^
and $
or may not be, in both of the case the code changes are working fine.
@@ -20,6 +20,9 @@ connection "gcp" { | |||
# If not set, no impersonation is done. | |||
#impersonate_service_account = "YOUR_SERVICE_ACCOUNT" | |||
|
|||
# `ignore_error_messages` (optional) - List of additional GCP error message pattern to ignore for all queries. |
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.
Is an error ignored if the message matches a value from here OR if the error code matches the other config arg?
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.
If the ignore_error_messages
has been set and the pattern matches with the error message the error will be ignore from here.
gcp/ignore_error_predicate.go
Outdated
// Add to support regex match as per error message | ||
for _, pattern := range gcpConfig.IgnoreErrorMessages { | ||
re := regexp.MustCompile(pattern) | ||
result := re.MatchString(types.ToString(gerr.Message)) |
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.
Do we need to cast with types.toString
? What type is the Message
property?
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.
Also, is there ever a case where Message
is not included as part of an error?
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.
Do we need to cast with types.toString? What type is the Message property?
No, we do not need to cast with types.toString
, the Message
property it self a string.
Also, is there ever a case where Message is not included as part of an error?
No, I have not face such type of scenario as of now.
This PR is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 30 days. |
This PR is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 30 days. |
This PR was closed because it has been stalled for 90 days with no activity. |
FWIW, I've squashed and rebased the commits from this PR here: https://github.com/pdecat/steampipe-plugin-gcp/tree/issue-286, and can confirm it works great :) I've integrated the changes in our custom build of the plugin here: https://github.com/pdecat/steampipe-plugin-gcp/tree/dev |
This PR is also working great to ignore issues when new regions are added, like is currently happening with
The following configuration allows to ignore them (along with service disabled errors):
|
gcp/ignore_error_predicate.go
Outdated
|
||
if gerr, ok := err.(*googleapi.Error); ok { | ||
|
||
// Add to support regex match as per error message | ||
for _, pattern := range gcpConfig.IgnoreErrorMessages { | ||
re := regexp.MustCompile(pattern) | ||
result := re.MatchString(gerr.Message) | ||
if result { | ||
return true | ||
} | ||
} | ||
|
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.
Turns out not all Google Cloud SDK APIs use the googleapi.Error
type, e.g. Redis APIs, so I've altered this part of the code to compare the error message of all errors:
if gerr, ok := err.(*googleapi.Error); ok { | |
// Add to support regex match as per error message | |
for _, pattern := range gcpConfig.IgnoreErrorMessages { | |
re := regexp.MustCompile(pattern) | |
result := re.MatchString(gerr.Message) | |
if result { | |
return true | |
} | |
} | |
logger := plugin.Logger(ctx) | |
logger.Trace("ignore_error_predicate.shouldIgnoreErrorPluginDefault", "err.Error()", err.Error()) | |
// Add to support regex match as per error message | |
for _, pattern := range gcpConfig.IgnoreErrorMessages { | |
logger.Trace("ignore_error_predicate.shouldIgnoreErrorPluginDefault", "message_pattern", pattern) | |
// TODO: maybe compile these at the connection level for performance reasons | |
re := regexp.MustCompile(pattern) | |
result := re.MatchString(err.Error()) | |
if result { | |
logger.Debug("ignore_error_predicate.shouldIgnoreErrorPluginDefault", "ignore_error_message", err.Error()) | |
return true | |
} | |
} | |
Without this change, API has not been used
cannot be ignored for Redis API calls.
Note that this requires enabling multiline regex matching with (?s)
as errors are serialized as:
2024-11-28 08:23:11.222 UTC [TRACE] steampipe-plugin-gcp.plugin: [TRACE] 1732782190328: ignore_error_predicate.shouldIgnoreErrorPluginDefault:
err.Error()=
| rpc error: code = PermissionDenied desc = Google Cloud Memorystore for Redis API has not been used in project my-project before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/redis.googleapis.com/overview?project=my-project then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.
| error details: name = ErrorInfo reason = SERVICE_DISABLED domain = googleapis.com metadata = map[consumer:projects/my-project service:redis.googleapis.com]
| error details: name = Help desc = Google developers console API activation url = https://console.developers.google.com/apis/api/redis.googleapis.com/overview?project=my-project
E.g.:
ignore_error_messages = [
"(?s)^.*API has not been used.*$",
"(?s)^.*Unsupported region.*$",
]
Also added some logs to the error code checks right below.
Pushed the changes here: pdecat@d8b31a2
Can submit an PR targeting this PR's branch if you want.
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.
@pdecat Yes please, we'd greatly appreciate a PR!
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.
Submitted #688
* fix: ignore error messages from all error types
Integration test logs
Logs
Example query results
Results