external_deps.bzl 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. load("@envoy_api//bazel:repository_locations_utils.bzl", "load_repository_locations_spec")
  2. # Envoy dependencies may be annotated with the following attributes:
  3. DEPENDENCY_ANNOTATIONS = [
  4. # Attribute specifying CPE (Common Platform Enumeration, see https://nvd.nist.gov/products/cpe) ID
  5. # of the dependency. The ID may be in v2.3 or v2.2 format, although v2.3 is prefferred. See
  6. # https://nvd.nist.gov/products/cpe for CPE format. Use single wildcard '*' for version and vector elements
  7. # i.e. 'cpe:2.3:a:nghttp2:nghttp2:*'. Use "N/A" for dependencies without CPE assigned.
  8. # This attribute is optional for components with use categories listed in the
  9. # USE_CATEGORIES_WITH_CPE_OPTIONAL
  10. "cpe",
  11. # A list of extensions when 'use_category' contains 'dataplane_ext' or 'observability_ext'.
  12. "extensions",
  13. # Additional dependencies loaded transitively via this dependency that are not tracked in
  14. # Envoy (see the external dependency at the given version for information).
  15. "implied_untracked_deps",
  16. # Project metadata.
  17. "project_desc",
  18. "project_name",
  19. "project_url",
  20. # Reflects the UTC date (YYYY-MM-DD format) for the dependency release. This
  21. # is when the dependency was updated in its repository. For dependencies
  22. # that have releases, this is the date of the release. For dependencies
  23. # without releases or for scenarios where we temporarily need to use a
  24. # commit, this date should be the date of the commit in UTC.
  25. "release_date",
  26. # List of the categories describing how the dependency is being used. This attribute is used
  27. # for automatic tracking of security posture of Envoy's dependencies.
  28. # Possible values are documented in the USE_CATEGORIES list below.
  29. # This attribute is mandatory for each dependecy.
  30. "use_category",
  31. # The dependency version. This may be either a tagged release (preferred)
  32. # or git SHA (as an exception when no release tagged version is suitable).
  33. "version",
  34. ]
  35. # NOTE: If a dependency use case is either dataplane or controlplane, the other uses are not needed
  36. # to be declared.
  37. USE_CATEGORIES = [
  38. # This dependency is used in API protos.
  39. "api",
  40. # This dependency is used in build process.
  41. "build",
  42. # This dependency is used to process xDS requests.
  43. "controlplane",
  44. # This dependency is used in processing downstream or upstream requests (core).
  45. "dataplane_core",
  46. # This dependency is used in processing downstream or upstream requests (extensions).
  47. "dataplane_ext",
  48. # This dependecy is used for logging, metrics or tracing (core). It may process unstrusted input.
  49. "observability_core",
  50. # This dependecy is used for logging, metrics or tracing (extensions). It may process unstrusted input.
  51. "observability_ext",
  52. # This dependency does not handle untrusted data and is used for various utility purposes.
  53. "other",
  54. # This dependency is used only in tests.
  55. "test_only",
  56. # Documentation generation
  57. "docs",
  58. # Developer tools (not used in build or docs)
  59. "devtools",
  60. ]
  61. # Components with these use categories are not required to specify the 'cpe'.
  62. USE_CATEGORIES_WITH_CPE_OPTIONAL = ["build", "other", "test_only", "api"]
  63. def _fail_missing_attribute(attr, key):
  64. fail("The '%s' attribute must be defined for external dependency " % attr + key)
  65. # Method for verifying content of the repository location specifications.
  66. #
  67. # We also remove repository metadata attributes so that further consumers, e.g.
  68. # http_archive, are not confused by them.
  69. def load_repository_locations(repository_locations_spec):
  70. locations = {}
  71. for key, location in load_repository_locations_spec(repository_locations_spec).items():
  72. mutable_location = dict(location)
  73. locations[key] = mutable_location
  74. if "sha256" not in location or len(location["sha256"]) == 0:
  75. _fail_missing_attribute("sha256", key)
  76. if "project_name" not in location:
  77. _fail_missing_attribute("project_name", key)
  78. if "project_desc" not in location:
  79. _fail_missing_attribute("project_desc", key)
  80. if "project_url" not in location:
  81. _fail_missing_attribute("project_url", key)
  82. project_url = location["project_url"]
  83. if not project_url.startswith("https://") and not project_url.startswith("http://"):
  84. fail("project_url must start with https:// or http://: " + project_url)
  85. if "version" not in location:
  86. _fail_missing_attribute("version", key)
  87. if "use_category" not in location:
  88. _fail_missing_attribute("use_category", key)
  89. use_category = location["use_category"]
  90. if "dataplane_ext" in use_category or "observability_ext" in use_category:
  91. if "extensions" not in location:
  92. _fail_missing_attribute("extensions", key)
  93. if "release_date" not in location:
  94. _fail_missing_attribute("release_date", key)
  95. release_date = location["release_date"]
  96. # Starlark doesn't have regexes.
  97. if len(release_date) != 10 or release_date[4] != "-" or release_date[7] != "-":
  98. fail("release_date must match YYYY-DD-MM: " + release_date)
  99. if "cpe" in location:
  100. cpe = location["cpe"]
  101. # Starlark doesn't have regexes.
  102. cpe_components = len(cpe.split(":"))
  103. # We allow cpe:2.3:a:foo:*:* and cpe:2.3.:a:foo:bar:* only.
  104. cpe_components_valid = (cpe_components == 6)
  105. cpe_matches = (cpe == "N/A" or (cpe.startswith("cpe:2.3:a:") and cpe.endswith(":*") and cpe_components_valid))
  106. if not cpe_matches:
  107. fail("CPE must match cpe:2.3:a:<facet>:<facet>:*: " + cpe)
  108. elif not [category for category in USE_CATEGORIES_WITH_CPE_OPTIONAL if category in location["use_category"]]:
  109. _fail_missing_attribute("cpe", key)
  110. for category in location["use_category"]:
  111. if category not in USE_CATEGORIES:
  112. fail("Unknown use_category value '" + category + "' for dependecy " + key)
  113. # Remove any extra annotations that we add, so that we don't confuse http_archive etc.
  114. for annotation in DEPENDENCY_ANNOTATIONS:
  115. if annotation in mutable_location:
  116. mutable_location.pop(annotation)
  117. return locations