|
8 | 8 | import pytest
|
9 | 9 |
|
10 | 10 | from cfnlint.context._mappings import Mappings
|
11 |
| -from cfnlint.context.context import Context |
| 11 | +from cfnlint.context.context import Context, Parameter |
12 | 12 | from cfnlint.jsonschema import ValidationError
|
13 | 13 | from cfnlint.jsonschema.validators import CfnTemplateValidator
|
14 | 14 |
|
@@ -247,7 +247,7 @@ def test_invalid_functions(name, instance, response):
|
247 | 247 | (
|
248 | 248 | "'bar' is not one of ['foo', "
|
249 | 249 | "'transformFirstKey', 'transformSecondKey', "
|
250 |
| - "'integers']" |
| 250 | + "'integers', 'accounts', 'environments']" |
251 | 251 | ),
|
252 | 252 | path=deque(["Fn::FindInMap", 0]),
|
253 | 253 | ),
|
@@ -296,9 +296,75 @@ def test_invalid_functions(name, instance, response):
|
296 | 296 | [],
|
297 | 297 | ),
|
298 | 298 | (
|
299 |
| - "Valid FindInMap with an top level key that is a Ref to pseudo param", |
| 299 | + "Valid FindInMap with an top level key that is a Ref to an account", |
| 300 | + {"Fn::FindInMap": ["accounts", {"Ref": "AWS::AccountId"}, "dev"]}, |
| 301 | + [ |
| 302 | + ( |
| 303 | + "bar", |
| 304 | + deque(["Mappings", "accounts", "123456789012", "dev"]), |
| 305 | + None, |
| 306 | + ) |
| 307 | + ], |
| 308 | + ), |
| 309 | + ( |
| 310 | + ( |
| 311 | + "Valid FindInMap with an top level key " |
| 312 | + "that is a Ref to non account non region" |
| 313 | + ), |
| 314 | + {"Fn::FindInMap": ["accounts", {"Ref": "AWS::StackName"}, "dev"]}, |
| 315 | + [ |
| 316 | + ( |
| 317 | + "bar", |
| 318 | + deque(["Mappings", "accounts", "123456789012", "dev"]), |
| 319 | + None, |
| 320 | + ) |
| 321 | + ], |
| 322 | + ), |
| 323 | + ( |
| 324 | + "Valid FindInMap with an top level key that is a Ref to a region", |
| 325 | + {"Fn::FindInMap": ["accounts", {"Ref": "AWS::Region"}, "bar"]}, |
| 326 | + [ |
| 327 | + ( |
| 328 | + "foo", |
| 329 | + deque(["Mappings", "accounts", "us-east-1", "bar"]), |
| 330 | + None, |
| 331 | + ) |
| 332 | + ], |
| 333 | + ), |
| 334 | + ( |
| 335 | + "Invalid FindInMap with an top level key that is a Ref to an account", |
| 336 | + {"Fn::FindInMap": ["accounts", {"Ref": "AWS::AccountId"}, "bar"]}, |
| 337 | + [ |
| 338 | + ( |
| 339 | + None, |
| 340 | + deque([]), |
| 341 | + ValidationError( |
| 342 | + ( |
| 343 | + "'bar' is not a second level key " |
| 344 | + "when {'Ref': 'AWS::AccountId'} is " |
| 345 | + "resolved for mapping 'accounts'" |
| 346 | + ), |
| 347 | + path=deque(["Fn::FindInMap", 2]), |
| 348 | + ), |
| 349 | + ) |
| 350 | + ], |
| 351 | + ), |
| 352 | + ( |
| 353 | + "Invalid FindInMap with an top level key that is a Ref to pseudo param", |
300 | 354 | {"Fn::FindInMap": ["foo", {"Ref": "AWS::AccountId"}, "second"]},
|
301 |
| - [], |
| 355 | + [ |
| 356 | + ( |
| 357 | + None, |
| 358 | + deque([]), |
| 359 | + ValidationError( |
| 360 | + ( |
| 361 | + "{'Ref': 'AWS::AccountId'} is not a " |
| 362 | + "first level key for mapping 'foo'" |
| 363 | + ), |
| 364 | + path=deque(["Fn::FindInMap", 1]), |
| 365 | + ), |
| 366 | + ) |
| 367 | + ], |
302 | 368 | ),
|
303 | 369 | (
|
304 | 370 | "Valid FindInMap with a second level key that is a Ref to pseudo param",
|
@@ -327,6 +393,78 @@ def test_invalid_functions(name, instance, response):
|
327 | 393 | {"Fn::FindInMap": ["integers", 1, 2]},
|
328 | 394 | [("Value", deque(["Mappings", "integers", "1", "2"]), None)],
|
329 | 395 | ),
|
| 396 | + ( |
| 397 | + ( |
| 398 | + "Valid FindInMap with a Ref to a parameter " |
| 399 | + "with allowed values for top level key" |
| 400 | + ), |
| 401 | + {"Fn::FindInMap": ["environments", {"Ref": "Environment"}, "foo"]}, |
| 402 | + [ |
| 403 | + ("one", deque(["Mappings", "environments", "dev", "foo"]), None), |
| 404 | + ("two", deque(["Mappings", "environments", "test", "foo"]), None), |
| 405 | + ], |
| 406 | + ), |
| 407 | + ( |
| 408 | + "Valid FindInMap with a Ref to a parameter for top level key", |
| 409 | + {"Fn::FindInMap": ["environments", {"Ref": "RandomString"}, "foo"]}, |
| 410 | + [], |
| 411 | + ), |
| 412 | + ( |
| 413 | + ( |
| 414 | + "Valid FindInMap with a Ref to accounts for top level " |
| 415 | + "key Ref to a ramom string for second level key" |
| 416 | + ), |
| 417 | + { |
| 418 | + "Fn::FindInMap": [ |
| 419 | + "accounts", |
| 420 | + {"Ref": "AWS::AccountId"}, |
| 421 | + {"Ref": "RandomString"}, |
| 422 | + ] |
| 423 | + }, |
| 424 | + [], |
| 425 | + ), |
| 426 | + ( |
| 427 | + ( |
| 428 | + "Valid FindInMap with a Ref to accounts for top level " |
| 429 | + "key Ref to an allowed value parameter for second level key" |
| 430 | + ), |
| 431 | + { |
| 432 | + "Fn::FindInMap": [ |
| 433 | + "accounts", |
| 434 | + {"Ref": "AWS::AccountId"}, |
| 435 | + {"Ref": "Environment"}, |
| 436 | + ] |
| 437 | + }, |
| 438 | + [], |
| 439 | + ), |
| 440 | + ( |
| 441 | + ( |
| 442 | + "Valid FindInMap with a Ref to a parameter " |
| 443 | + "with allowed values for second level key" |
| 444 | + ), |
| 445 | + {"Fn::FindInMap": ["environments", "lion", {"Ref": "Environment"}]}, |
| 446 | + [ |
| 447 | + ("one", deque(["Mappings", "environments", "lion", "dev"]), None), |
| 448 | + ("two", deque(["Mappings", "environments", "lion", "test"]), None), |
| 449 | + ("three", deque(["Mappings", "environments", "lion", "prod"]), None), |
| 450 | + ], |
| 451 | + ), |
| 452 | + ( |
| 453 | + "Valid FindInMap with a Ref to a parameter for top level key", |
| 454 | + {"Fn::FindInMap": ["environments", {"Ref": "RandomString"}, "foo"]}, |
| 455 | + [], |
| 456 | + ), |
| 457 | + ( |
| 458 | + "Valid FindInMap with a Ref to a parameter and a Ref to pseudo parameter", |
| 459 | + { |
| 460 | + "Fn::FindInMap": [ |
| 461 | + "accounts", |
| 462 | + {"Ref": "AWS::AccountId"}, |
| 463 | + {"Ref": "RandomString"}, |
| 464 | + ] |
| 465 | + }, |
| 466 | + [], |
| 467 | + ), |
330 | 468 | (
|
331 | 469 | "Valid FindInMap with a bad second key and default",
|
332 | 470 | {"Fn::FindInMap": ["foo", "first", "third", {"DefaultValue": "default"}]},
|
@@ -356,14 +494,41 @@ def test_invalid_functions(name, instance, response):
|
356 | 494 | )
|
357 | 495 | def test_valid_functions(name, instance, response):
|
358 | 496 | context = Context(
|
| 497 | + parameters={ |
| 498 | + "RandomString": Parameter( |
| 499 | + { |
| 500 | + "Type": "String", |
| 501 | + } |
| 502 | + ), |
| 503 | + "Environment": Parameter( |
| 504 | + { |
| 505 | + "Type": "String", |
| 506 | + "AllowedValues": ["dev", "test", "prod"], |
| 507 | + } |
| 508 | + ), |
| 509 | + }, |
359 | 510 | mappings=Mappings.create_from_dict(
|
360 | 511 | {
|
361 | 512 | "foo": {"first": {"second": "bar"}},
|
362 | 513 | "transformFirstKey": {"Fn::Transform": {"second": "bar"}},
|
363 | 514 | "transformSecondKey": {"first": {"Fn::Transform": "bar"}},
|
364 | 515 | "integers": {"1": {"2": "Value"}},
|
| 516 | + "accounts": { |
| 517 | + "123456789012": {"dev": "bar"}, |
| 518 | + "us-east-1": {"bar": "foo"}, |
| 519 | + }, |
| 520 | + "environments": { |
| 521 | + "dev": {"foo": "one"}, |
| 522 | + "test": {"foo": "two"}, |
| 523 | + "prod": {"bar": "three"}, |
| 524 | + "lion": { |
| 525 | + "dev": "one", |
| 526 | + "test": "two", |
| 527 | + "prod": "three", |
| 528 | + }, |
| 529 | + }, |
365 | 530 | }
|
366 |
| - ) |
| 531 | + ), |
367 | 532 | )
|
368 | 533 | _resolve(name, instance, response, context=context)
|
369 | 534 |
|
|
0 commit comments