Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changesets/fix_license_handling.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
### Fix: Proper handling of licenses in a warning state

We allowed licenses in a warning state to bypass enforcement because we weren't returning an error, only the limits. This was happening, I think, because there's middleware handling expired licenses but not licenses in a warning state. So, we assumed that there'd be same kind of handling for licenses in a warning state. Alas, there's not.

We now error out if there are restricted features in use.

By [@aaronarinder](https://github.com/aaronarinder) in https://github.com/apollographql/router/pull/8768
6 changes: 3 additions & 3 deletions .config/mise/config.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[tools]
# renovate-automation: rustc version
rust = "1.91.1"
"aqua:cargo-bins/cargo-binstall" = "1.16.2"
"aqua:cargo-bins/cargo-binstall" = "1.16.3"
"cargo:cargo-nextest" = "0.9.70"
"cargo:cargo-deny" = "0.18.2"
"cargo:cargo-deny" = "0.19.0"
"cargo:cargo-edit" = "0.13.0"
"cargo:cargo-about" = "0.8.0"
"cargo:cargo-insta" = "1.38.0"
Expand All @@ -13,7 +13,7 @@ rust = "1.91.1"
"cargo:typos-cli" = "1.31.1"
protoc = "33.1"
gh = "2.72.0"
helm = "3.19.2"
helm = "3.19.4"
helm-docs = "1.14.2"
yq = "4.49.2"
jq = "1.8.1"
Expand Down
26 changes: 13 additions & 13 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1469,9 +1469,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"

[[package]]
name = "bytes"
version = "1.11.0"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3"
checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33"
dependencies = [
"serde",
]
Expand Down Expand Up @@ -4095,9 +4095,9 @@ dependencies = [

[[package]]
name = "lru"
version = "0.16.2"
version = "0.16.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96051b46fc183dc9cd4a223960ef37b9af631b55191852a8274bfef064cda20f"
checksum = "a1dc47f592c06f33f8e3aea9591776ec7c9f9e4124778ff8a3c3b87159f7e593"
dependencies = [
"hashbrown 0.16.1",
]
Expand Down Expand Up @@ -4425,9 +4425,9 @@ dependencies = [

[[package]]
name = "num-conv"
version = "0.1.0"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050"

[[package]]
name = "num-integer"
Expand Down Expand Up @@ -6791,32 +6791,32 @@ dependencies = [

[[package]]
name = "time"
version = "0.3.44"
version = "0.3.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d"
checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c"
dependencies = [
"deranged",
"itoa",
"libc",
"num-conv",
"num_threads",
"powerfmt",
"serde",
"serde_core",
"time-core",
"time-macros",
]

[[package]]
name = "time-core"
version = "0.1.6"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b"
checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca"

[[package]]
name = "time-macros"
version = "0.2.24"
version = "0.2.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3"
checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215"
dependencies = [
"num-conv",
"time-core",
Expand Down
22 changes: 14 additions & 8 deletions apollo-router/src/state_machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -354,13 +354,15 @@ impl<FA: RouterSuperServiceFactory> State<FA> {
LicenseState::LicensedWarn { limits } => {
if report.uses_restricted_features() {
tracing::error!(
"License has expired. The Router will soon stop serving requests. In order to enable these features for a self-hosted instance of Apollo Router, the Router must be connected to a graph in GraphOS that provides an active license for the following features:\n\n{}\n\nSee {LICENSE_EXPIRED_URL} for more information.",
"License violation, the router is using features not available for your license:\n\n{}\n\nThe license warning period has started. The Router will stop serving requests after the license expires. See {LICENSE_EXPIRED_URL} for more information.",
report
);
limits
return Err(ApolloRouterError::LicenseViolation(
report.restricted_features_in_use(),
));
} else {
tracing::error!(
"License has expired. The Router will soon stop serving requests. In order to enable these features for a self-hosted instance of Apollo Router, the Router must be connected to a graph in GraphOS that provides an active license for the following features:\n\n{:?}\n\nSee {LICENSE_EXPIRED_URL} for more information.",
tracing::warn!(
"License warning period has started. The Router will stop serving requests after the license expires. In order to continue using these features for a self-hosted instance of Apollo Router, the Router must be connected to a graph in GraphOS that provides an active license for the following features:\n\n{:?}\n\nSee {LICENSE_EXPIRED_URL} for more information.",
// The report does not contain any features because they are contained within the allowedFeatures claim,
// therefore we output all of the allowed features that the user's license enables them to use.
license.get_allowed_features()
Expand Down Expand Up @@ -1146,8 +1148,10 @@ mod tests {
#[case] config: Arc<Configuration>,
#[case] allowed_features: Vec<AllowedFeature>,
) {
let router_factory = create_mock_router_configurator(1);
let (server_factory, shutdown_receivers) = create_mock_server_factory(1);
// errors happen before this would be hit; so, 0, but we still need to pass _something_ to
// execute()
let router_factory = create_mock_router_configurator(0);
let (server_factory, shutdown_receivers) = create_mock_server_factory(0);

assert_matches!(
execute(
Expand All @@ -1166,9 +1170,11 @@ mod tests {
])
)
.await,
Ok(())
// this is where the real test happens; we expect a license violation if we're using
// features that aren't being paid for
Err(ApolloRouterError::LicenseViolation(_))
);
assert_eq!(shutdown_receivers.0.lock().len(), 1);
assert_eq!(shutdown_receivers.0.lock().len(), 0);
}

#[test(tokio::test)]
Expand Down
3 changes: 3 additions & 0 deletions apollo-router/tests/integration/allowed_features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,9 @@ async fn feature_violation_when_license_past_warn_at_but_not_expired_allowed_fea
.build()
.await;

router.replace_config_string("http://localhost:{{PRODUCTS_PORT}}", "localhost:4001");
router.replace_config_string("http://localhost:{{ACCOUNTS_PORT}}", "localhost:4002");

router.start().await;
router
.assert_error_log_contained(LICENSE_ALLOWED_FEATURES_DOES_NOT_INCLUDE_FEATURE_MSG)
Expand Down
2 changes: 0 additions & 2 deletions deny.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ git-fetch-with-cli = true
# rustsec advisory exemptions
ignore = [
"RUSTSEC-2023-0071",
"RUSTSEC-2024-0376", # we do not use tonic::transport::Server
"RUSTSEC-2024-0421", # we only resolve trusted subgraphs

# protobuf is used only through prometheus crates, enforced by
# a `[bans]` entry below. in the prometheus crates, only the protobuf
Expand Down