Skip to content

Commit 7047f1f

Browse files
committed
feat(mmds): Add metric to count GET requests without tokens
The metric is useful for users to track whether v1-style requests are issued or not inside a guest. Signed-off-by: Takahiro Itazuri <[email protected]>
1 parent 0036de6 commit 7047f1f

File tree

6 files changed

+29
-8
lines changed

6 files changed

+29
-8
lines changed

CHANGELOG.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@ and this project adheres to
2525
"X-aws-ec2-metadata-token" and "X-aws-ec2-metadata-token-ttl-seconds")
2626
alongside the MMDS-specific ones.
2727
- [#5290](https://github.com/firecracker-microvm/firecracker/pull/5290): Added
28-
`mmds.rx_invalid_token` metric to track the number of GET requests that were
29-
rejected due to token validation failures in MMDS version 2. This metric also
30-
counts requests that would be rejected in MMDS version 2 when MMDS version 1
31-
is configured. This helps users assess readiness for migrating to MMDS version
32-
2.
28+
`mmds.rx_invalid_token` and `mmds.rx_no_token` metrics to track the number of
29+
GET requests that were rejected due to token validation failures in MMDS
30+
version 2. These metrics also count requests that would be rejected in MMDS
31+
version 2 when MMDS version 1 is configured. They helps users assess readiness
32+
for migrating to MMDS version 2.
3333

3434
### Changed
3535

docs/mmds/mmds-user-guide.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,8 +235,9 @@ As in version 2, version 1 also supports a session oriented method in order to
235235
make the migration easier. See [the next section](#version-2) for the session
236236
oriented method. Note that version 1 returns a successful response to a `GET`
237237
request even with an invalid token or no token not to break existing workloads.
238-
`mmds.rx_invalid_token` metric tracks the number of `GET` requests with invalid
239-
tokens, helping users evaluate their readiness for migrating to MMDS version 2.
238+
`mmds.rx_invalid_token` and `mmds.rx_no_token` metrics track the number of `GET`
239+
requests with invalid tokens and missing tokens respectively, helping users
240+
evaluate their readiness for migrating to MMDS version 2.
240241

241242
Requests containing any other HTTP methods than `GET` and `PUT` will receive
242243
**405 Method Not Allowed** error.

src/vmm/src/logger/metrics.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,8 @@ pub struct MmdsMetrics {
541541
pub rx_bad_eth: SharedIncMetric,
542542
/// The number of GET requests with invalid tokens.
543543
pub rx_invalid_token: SharedIncMetric,
544+
/// The number of GET requests with no tokens.
545+
pub rx_no_token: SharedIncMetric,
544546
/// The total number of successful receive operations by the MMDS.
545547
pub rx_count: SharedIncMetric,
546548
/// The total number of bytes sent by the MMDS.
@@ -565,6 +567,7 @@ impl MmdsMetrics {
565567
rx_accepted_unusual: SharedIncMetric::new(),
566568
rx_bad_eth: SharedIncMetric::new(),
567569
rx_invalid_token: SharedIncMetric::new(),
570+
rx_no_token: SharedIncMetric::new(),
568571
rx_count: SharedIncMetric::new(),
569572
tx_bytes: SharedIncMetric::new(),
570573
tx_count: SharedIncMetric::new(),

src/vmm/src/mmds/mod.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ fn respond_to_get_request_v1(mmds: &Mmds, request: Request) -> Response {
154154
}
155155
}
156156
None => {
157-
// TODO: Increment a metric that will be added in an upcoming commit.
157+
METRICS.mmds.rx_no_token.inc();
158158
}
159159
}
160160

@@ -169,6 +169,7 @@ fn respond_to_get_request_v2(mmds: &Mmds, request: Request) -> Response {
169169
) {
170170
Some((_, token)) => token,
171171
None => {
172+
METRICS.mmds.rx_no_token.inc();
172173
let error_msg = VmmMmdsError::NoTokenProvided.to_string();
173174
return build_response(
174175
request.http_version(),
@@ -554,9 +555,11 @@ mod tests {
554555
MediaType::ApplicationJson,
555556
);
556557
let prev_rx_invalid_token = METRICS.mmds.rx_invalid_token.count();
558+
let prev_rx_no_token = METRICS.mmds.rx_no_token.count();
557559
let actual_response = convert_to_response(mmds.clone(), request);
558560
assert_eq!(actual_response, expected_response);
559561
assert_eq!(prev_rx_invalid_token, METRICS.mmds.rx_invalid_token.count());
562+
assert_eq!(prev_rx_no_token + 1, METRICS.mmds.rx_no_token.count());
560563

561564
// Test valid v2 request.
562565
let request = Request::try_from(
@@ -581,9 +584,11 @@ mod tests {
581584
MediaType::ApplicationJson,
582585
);
583586
let prev_rx_invalid_token = METRICS.mmds.rx_invalid_token.count();
587+
let prev_rx_no_token = METRICS.mmds.rx_no_token.count();
584588
let actual_response = convert_to_response(mmds.clone(), request);
585589
assert_eq!(actual_response, expected_response);
586590
assert_eq!(prev_rx_invalid_token, METRICS.mmds.rx_invalid_token.count());
591+
assert_eq!(prev_rx_no_token, METRICS.mmds.rx_no_token.count());
587592

588593
// Test GET request with invalid token is accepted when v1 is configured.
589594
let (request, expected_response) = generate_request_and_expected_response(
@@ -593,12 +598,14 @@ mod tests {
593598
MediaType::ApplicationJson,
594599
);
595600
let prev_rx_invalid_token = METRICS.mmds.rx_invalid_token.count();
601+
let prev_rx_no_token = METRICS.mmds.rx_no_token.count();
596602
let actual_response = convert_to_response(mmds, request);
597603
assert_eq!(actual_response, expected_response);
598604
assert_eq!(
599605
prev_rx_invalid_token + 1,
600606
METRICS.mmds.rx_invalid_token.count()
601607
);
608+
assert_eq!(prev_rx_no_token, METRICS.mmds.rx_no_token.count());
602609
}
603610

604611
#[test]
@@ -734,9 +741,11 @@ mod tests {
734741
MediaType::ApplicationJson,
735742
);
736743
let prev_rx_invalid_token = METRICS.mmds.rx_invalid_token.count();
744+
let prev_rx_no_token = METRICS.mmds.rx_no_token.count();
737745
let actual_response = convert_to_response(mmds.clone(), request);
738746
assert_eq!(actual_response, expected_response);
739747
assert_eq!(prev_rx_invalid_token, METRICS.mmds.rx_invalid_token.count());
748+
assert_eq!(prev_rx_no_token, METRICS.mmds.rx_no_token.count());
740749

741750
// Test invalid customer header value is ignored if not PUT request to /latest/api/token.
742751
#[rustfmt::skip]
@@ -796,8 +805,10 @@ mod tests {
796805
let mut expected_response = Response::new(Version::Http10, StatusCode::Unauthorized);
797806
expected_response.set_content_type(MediaType::PlainText);
798807
expected_response.set_body(Body::new(VmmMmdsError::NoTokenProvided.to_string()));
808+
let prev_rx_no_token = METRICS.mmds.rx_no_token.count();
799809
let actual_response = convert_to_response(mmds.clone(), request);
800810
assert_eq!(actual_response, expected_response);
811+
assert_eq!(prev_rx_no_token + 1, METRICS.mmds.rx_no_token.count());
801812

802813
// Create a new MMDS token that expires in one second.
803814
let request = Request::try_from(
@@ -830,12 +841,14 @@ mod tests {
830841
expected_response.set_content_type(MediaType::PlainText);
831842
expected_response.set_body(Body::new(VmmMmdsError::InvalidToken.to_string()));
832843
let prev_rx_invalid_token = METRICS.mmds.rx_invalid_token.count();
844+
let prev_rx_no_token = METRICS.mmds.rx_no_token.count();
833845
let actual_response = convert_to_response(mmds.clone(), request);
834846
assert_eq!(actual_response, expected_response);
835847
assert_eq!(
836848
prev_rx_invalid_token + 1,
837849
METRICS.mmds.rx_invalid_token.count()
838850
);
851+
assert_eq!(prev_rx_no_token, METRICS.mmds.rx_no_token.count());
839852

840853
// Wait for the second token to expire.
841854
std::thread::sleep(Duration::from_secs(1));

tests/host_tools/fcmetrics.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ def validate_fc_metrics(metrics):
186186
"rx_accepted_unusual",
187187
"rx_bad_eth",
188188
"rx_invalid_token",
189+
"rx_no_token",
189190
"rx_count",
190191
"tx_bytes",
191192
"tx_count",

tests/integration_tests/functional/test_mmds.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ def test_mmds_token(uvm_plain, version, imds_compat):
158158
)
159159
metrics = test_microvm.flush_metrics()
160160
assert metrics["mmds"]["rx_invalid_token"] == 0
161+
assert metrics["mmds"]["rx_no_token"] == 1
161162

162163
# GET request with invalid token
163164
cmd = (
@@ -172,13 +173,15 @@ def test_mmds_token(uvm_plain, version, imds_compat):
172173
run_guest_cmd(ssh_connection, cmd, "MMDS token not valid.")
173174
metrics = test_microvm.flush_metrics()
174175
assert metrics["mmds"]["rx_invalid_token"] == 1
176+
assert metrics["mmds"]["rx_no_token"] == 0
175177

176178
# Get request with valid token
177179
token = generate_mmds_session_token(ssh_connection, DEFAULT_IPV4, 60, imds_compat)
178180
cmd = generate_mmds_get_request(DEFAULT_IPV4, token, False, imds_compat) + "foo"
179181
run_guest_cmd(ssh_connection, cmd, "bar")
180182
metrics = test_microvm.flush_metrics()
181183
assert metrics["mmds"]["rx_invalid_token"] == 0
184+
assert metrics["mmds"]["rx_no_token"] == 0
182185

183186

184187
@pytest.mark.parametrize("version", MMDS_VERSIONS)

0 commit comments

Comments
 (0)