add maxmind country db support#31147
Conversation
|
Hi @hwyuan, welcome and thank you for your contribution. We will try to review your Pull Request as quickly as possible. In the meantime, please take a look at the contribution guidelines if you have not done so already. |
|
CC @envoyproxy/api-shepherds: Your approval is needed for changes made to |
ab7875c to
f0505e0
Compare
|
/retest |
|
cc @JuniorHsu |
JuniorHsu
left a comment
There was a problem hiding this comment.
also needs changelogs/current.yaml change
There was a problem hiding this comment.
by seeing this comment, should we do oneof in proto so we only allow either country or city map?
There was a problem hiding this comment.
makes sense, let me update the PR to try oneof
There was a problem hiding this comment.
An oneof change of the existing non-oneof field may break the backward compatibility in ProtoBuf, you should not change it and add configuration time exception to notice the user setting both country and city databases is not valid.
There was a problem hiding this comment.
sure, let's throw Exception in the constructor of GeoipProviderConfig
There was a problem hiding this comment.
since we are adding a new field country_db_path_ in this PR, and users will only be able to pick country_db_path_ or city_db_path after this change, i.e., currently they would either configure city_db_path_ or not using it, would we still have backward compatibility issues of we can adopt oneof directly in proto definition in this PR?
There was a problem hiding this comment.
It does not depend on how you use the field. The ProtoBuf does not support oneof backward compatibility and it may cause certain issues. Please refer to the ProtoBuf doc and Envoy API style (Prefer multiple fields with defined precedence over boolean overloads of fields or oneof).
There was a problem hiding this comment.
#30851 This is a pretty recent policy change for discouraging oneof. Thanks for the pointer.
As my understanding, some config generation tools have different setup with oneof and non-oneof so moving in/out oneof might causing compatibility issue as well.
There was a problem hiding this comment.
got it, thank you both for the context. will update the PR to add the config time exception
There was a problem hiding this comment.
this function has lots of similarity with lookupInCityDb. could we refactor to achieve DRY if it's not too hard?
There was a problem hiding this comment.
there are indeed similarities in these lookup function and ideally be better abstracted, wonder if we could do the refacor in a seperate PR so that this PR focuses on adding country db support
There was a problem hiding this comment.
i'll defer to code owner @nezdolik @ravenblackx
There was a problem hiding this comment.
Given that there is already similar duplicated code prior to this PR and PR adds more duplication, is good opportunity to tackle refactor here.
There was a problem hiding this comment.
let me give it a try, was worried that refactoring here might make this PR complicated to review, maybe could discuss more once there is a draft commit
There was a problem hiding this comment.
seems one possible approach is to have a common lookupInMaxmindDb function, and then we pass the db_type and maxmind_db database pointer to this function, where lookupInMaxmindDb will call related isLookupEnableForDbType and populateGeoLookupResultForDbType functions, where db-specific logics are handled.
What do you think about the approach? also still feels like might be better to do in a separate PR to it's cleaner and easier to review (and to revert if ever needed) as other db lookup functions will be touched, thoughts? @nezdolik
pseudocode
void GeoipProvider::lookupInMaxmindDb(
const Network::Address::InstanceConstSharedPtr& remote_address,
absl::flat_hash_map<std::string, std::string>& lookup_result,
const std::string& db_type /* we can make db_type a enum */,
const std::string& stat_prefix /* e.g. city for city_db */,
const MaxmindDbPtr& maxmind_db /* passing db pointer */,
) const {
if (isLookupEnableForDbType(db_type))
ASSERT(maxmind_db, fmt.format("Maxmind {} database is not initialised for performing lookups", stat_prefix));
int mmdb_error;
const uint32_t n_prev_hits = lookup_result.size();
MMDB_lookup_result_s mmdb_lookup_result = MMDB_lookup_sockaddr(
maxmind_db.get(), reinterpret_cast<const sockaddr*>(remote_address->sockAddr()), &mmdb_error);
if (!mmdb_error) {
MMDB_entry_data_list_s* entry_data_list;
int status = MMDB_get_entry_data_list(&mmdb_lookup_result.entry, &entry_data_list);
if (status == MMDB_SUCCESS) {
// populate headers
populateGeoLookupResultForDbType(db_type)
if (lookup_result.size() > n_prev_hits) {
config_->incHit(fmt.format("{}_db", stat_prefix));
}
MMDB_free_entry_data_list(entry_data_list);
}
} else {
config_->incLookupError(fmt.format("{}_db", stat_prefix));
}
config_->incTotal(fmt.format("{}_db", stat_prefix));
}
}
There was a problem hiding this comment.
drafted an example PR in #31490, please take a look when you have a chance
8722b63 to
68d7960
Compare
JuniorHsu
left a comment
There was a problem hiding this comment.
I've done the first pass modulo nits and questions. Over to owner/maintainer's review @nezdolik @ravenblackx
There was a problem hiding this comment.
i'll defer to code owner @nezdolik @ravenblackx
There was a problem hiding this comment.
Not sure if we want to dup this warning to city_db_path as well. @nezdolik @ravenblackx thought?
There was a problem hiding this comment.
nit: move this field in the end of the proto message, as it is the most recently added.
There was a problem hiding this comment.
Is fine to have warning only here, given that there will validation error when user sets both fields (so they should read docs for both fields).
5399e8d to
042ef2b
Compare
|
/retest |
042ef2b to
006b66d
Compare
Signed-off-by: Haowei Yuan <hyuan@wustl.edu>
006b66d to
8e12495
Compare
nezdolik
left a comment
There was a problem hiding this comment.
Looking at Maxmind comparison of city and country databases (in the bottom of the page), country one contains subset of fields from city, so there will be no case when someone needs both databases to be configured.
There was a problem hiding this comment.
nit: move this field in the end of the proto message, as it is the most recently added.
There was a problem hiding this comment.
Is fine to have warning only here, given that there will validation error when user sets both fields (so they should read docs for both fields).
| @@ -23,7 +23,13 @@ option (xds.annotations.v3.file_status).work_in_progress = true; | |||
| // :ref:`anon_db_path <envoy_v3_api_field_extensions.geoip_providers.maxmind.v3.MaxMindConfig.anon_db_path>` must be configured. | |||
There was a problem hiding this comment.
sure, does it make sense to move the warning of "at most one of country_db_path and city_db_path can be configured" here so that these instructions are together? and remove it from line 30 below
There was a problem hiding this comment.
Given that there is already similar duplicated code prior to this PR and PR adds more duplication, is good opportunity to tackle refactor here.
| EXPECT_DEATH(initializeProvider(config_yaml), ".*Unable to open Maxmind database file.*"); | ||
| } | ||
|
|
||
| TEST_F(GeoipProviderTest, ValidConfigCountryDbSuccessfulLookup) { |
There was a problem hiding this comment.
can you add tests to geoip_filter_integration_test.cc as well?
| message MaxMindConfig { | ||
| // Full file path to the Maxmind country database, e.g. /etc/GeoLite2-Country.mmdb. | ||
| // Database file is expected to have .mmdb extension. | ||
| // Note that only one of country_db_path and city_db_path can be set. |
There was a problem hiding this comment.
Add reference to proto fields, e.g. :ref:city_db_path <envoy_v3_api_field_extensions.geoip_providers.maxmind.v3.MaxMindConfig.city_db_path>
Signed-off-by: Haowei Yuan <hyuan@wustl.edu>
|
This pull request has been automatically marked as stale because it has not had activity in the last 30 days. It will be closed in 7 days if no further activity occurs. Please feel free to give a status update now, ping for review, or re-open when it's ready. Thank you for your contributions! |
|
This pull request has been automatically closed because it has not had activity in the last 37 days. Please feel free to give a status update now, ping for review, or re-open when it's ready. Thank you for your contributions! |
|
it did require more work on pr to be done |
Commit Message: add maxmind country db support
Additional Description:
Support maxmind country db in geoip maxmind provider.
Since both country db and city db can populate country info, we allow at most one of country db and city db can be configured to avoid ambiguity.
Risk Level: Low
Testing: unit test
Docs Changes: TODO
Release Notes: TODO
Platform Specific Features:
[Optional Fixes #Issue] #30956