m2m模型翻译
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

244 lines
8.1 KiB

6 months ago
  1. from __future__ import absolute_import
  2. from kafka.errors import IllegalArgumentError
  3. # enum in stdlib as of py3.4
  4. try:
  5. from enum import IntEnum # pylint: disable=import-error
  6. except ImportError:
  7. # vendored backport module
  8. from kafka.vendor.enum34 import IntEnum
  9. class ResourceType(IntEnum):
  10. """Type of kafka resource to set ACL for
  11. The ANY value is only valid in a filter context
  12. """
  13. UNKNOWN = 0,
  14. ANY = 1,
  15. CLUSTER = 4,
  16. DELEGATION_TOKEN = 6,
  17. GROUP = 3,
  18. TOPIC = 2,
  19. TRANSACTIONAL_ID = 5
  20. class ACLOperation(IntEnum):
  21. """Type of operation
  22. The ANY value is only valid in a filter context
  23. """
  24. ANY = 1,
  25. ALL = 2,
  26. READ = 3,
  27. WRITE = 4,
  28. CREATE = 5,
  29. DELETE = 6,
  30. ALTER = 7,
  31. DESCRIBE = 8,
  32. CLUSTER_ACTION = 9,
  33. DESCRIBE_CONFIGS = 10,
  34. ALTER_CONFIGS = 11,
  35. IDEMPOTENT_WRITE = 12
  36. class ACLPermissionType(IntEnum):
  37. """An enumerated type of permissions
  38. The ANY value is only valid in a filter context
  39. """
  40. ANY = 1,
  41. DENY = 2,
  42. ALLOW = 3
  43. class ACLResourcePatternType(IntEnum):
  44. """An enumerated type of resource patterns
  45. More details on the pattern types and how they work
  46. can be found in KIP-290 (Support for prefixed ACLs)
  47. https://cwiki.apache.org/confluence/display/KAFKA/KIP-290%3A+Support+for+Prefixed+ACLs
  48. """
  49. ANY = 1,
  50. MATCH = 2,
  51. LITERAL = 3,
  52. PREFIXED = 4
  53. class ACLFilter(object):
  54. """Represents a filter to use with describing and deleting ACLs
  55. The difference between this class and the ACL class is mainly that
  56. we allow using ANY with the operation, permission, and resource type objects
  57. to fetch ALCs matching any of the properties.
  58. To make a filter matching any principal, set principal to None
  59. """
  60. def __init__(
  61. self,
  62. principal,
  63. host,
  64. operation,
  65. permission_type,
  66. resource_pattern
  67. ):
  68. self.principal = principal
  69. self.host = host
  70. self.operation = operation
  71. self.permission_type = permission_type
  72. self.resource_pattern = resource_pattern
  73. self.validate()
  74. def validate(self):
  75. if not isinstance(self.operation, ACLOperation):
  76. raise IllegalArgumentError("operation must be an ACLOperation object, and cannot be ANY")
  77. if not isinstance(self.permission_type, ACLPermissionType):
  78. raise IllegalArgumentError("permission_type must be an ACLPermissionType object, and cannot be ANY")
  79. if not isinstance(self.resource_pattern, ResourcePatternFilter):
  80. raise IllegalArgumentError("resource_pattern must be a ResourcePatternFilter object")
  81. def __repr__(self):
  82. return "<ACL principal={principal}, resource={resource}, operation={operation}, type={type}, host={host}>".format(
  83. principal=self.principal,
  84. host=self.host,
  85. operation=self.operation.name,
  86. type=self.permission_type.name,
  87. resource=self.resource_pattern
  88. )
  89. def __eq__(self, other):
  90. return all((
  91. self.principal == other.principal,
  92. self.host == other.host,
  93. self.operation == other.operation,
  94. self.permission_type == other.permission_type,
  95. self.resource_pattern == other.resource_pattern
  96. ))
  97. def __hash__(self):
  98. return hash((
  99. self.principal,
  100. self.host,
  101. self.operation,
  102. self.permission_type,
  103. self.resource_pattern,
  104. ))
  105. class ACL(ACLFilter):
  106. """Represents a concrete ACL for a specific ResourcePattern
  107. In kafka an ACL is a 4-tuple of (principal, host, operation, permission_type)
  108. that limits who can do what on a specific resource (or since KIP-290 a resource pattern)
  109. Terminology:
  110. Principal -> This is the identifier for the user. Depending on the authorization method used (SSL, SASL etc)
  111. the principal will look different. See http://kafka.apache.org/documentation/#security_authz for details.
  112. The principal must be on the format "User:<name>" or kafka will treat it as invalid. It's possible to use
  113. other principal types than "User" if using a custom authorizer for the cluster.
  114. Host -> This must currently be an IP address. It cannot be a range, and it cannot be a domain name.
  115. It can be set to "*", which is special cased in kafka to mean "any host"
  116. Operation -> Which client operation this ACL refers to. Has different meaning depending
  117. on the resource type the ACL refers to. See https://docs.confluent.io/current/kafka/authorization.html#acl-format
  118. for a list of which combinations of resource/operation that unlocks which kafka APIs
  119. Permission Type: Whether this ACL is allowing or denying access
  120. Resource Pattern -> This is a representation of the resource or resource pattern that the ACL
  121. refers to. See the ResourcePattern class for details.
  122. """
  123. def __init__(
  124. self,
  125. principal,
  126. host,
  127. operation,
  128. permission_type,
  129. resource_pattern
  130. ):
  131. super(ACL, self).__init__(principal, host, operation, permission_type, resource_pattern)
  132. self.validate()
  133. def validate(self):
  134. if self.operation == ACLOperation.ANY:
  135. raise IllegalArgumentError("operation cannot be ANY")
  136. if self.permission_type == ACLPermissionType.ANY:
  137. raise IllegalArgumentError("permission_type cannot be ANY")
  138. if not isinstance(self.resource_pattern, ResourcePattern):
  139. raise IllegalArgumentError("resource_pattern must be a ResourcePattern object")
  140. class ResourcePatternFilter(object):
  141. def __init__(
  142. self,
  143. resource_type,
  144. resource_name,
  145. pattern_type
  146. ):
  147. self.resource_type = resource_type
  148. self.resource_name = resource_name
  149. self.pattern_type = pattern_type
  150. self.validate()
  151. def validate(self):
  152. if not isinstance(self.resource_type, ResourceType):
  153. raise IllegalArgumentError("resource_type must be a ResourceType object")
  154. if not isinstance(self.pattern_type, ACLResourcePatternType):
  155. raise IllegalArgumentError("pattern_type must be an ACLResourcePatternType object")
  156. def __repr__(self):
  157. return "<ResourcePattern type={}, name={}, pattern={}>".format(
  158. self.resource_type.name,
  159. self.resource_name,
  160. self.pattern_type.name
  161. )
  162. def __eq__(self, other):
  163. return all((
  164. self.resource_type == other.resource_type,
  165. self.resource_name == other.resource_name,
  166. self.pattern_type == other.pattern_type,
  167. ))
  168. def __hash__(self):
  169. return hash((
  170. self.resource_type,
  171. self.resource_name,
  172. self.pattern_type
  173. ))
  174. class ResourcePattern(ResourcePatternFilter):
  175. """A resource pattern to apply the ACL to
  176. Resource patterns are used to be able to specify which resources an ACL
  177. describes in a more flexible way than just pointing to a literal topic name for example.
  178. Since KIP-290 (kafka 2.0) it's possible to set an ACL for a prefixed resource name, which
  179. can cut down considerably on the number of ACLs needed when the number of topics and
  180. consumer groups start to grow.
  181. The default pattern_type is LITERAL, and it describes a specific resource. This is also how
  182. ACLs worked before the introduction of prefixed ACLs
  183. """
  184. def __init__(
  185. self,
  186. resource_type,
  187. resource_name,
  188. pattern_type=ACLResourcePatternType.LITERAL
  189. ):
  190. super(ResourcePattern, self).__init__(resource_type, resource_name, pattern_type)
  191. self.validate()
  192. def validate(self):
  193. if self.resource_type == ResourceType.ANY:
  194. raise IllegalArgumentError("resource_type cannot be ANY")
  195. if self.pattern_type in [ACLResourcePatternType.ANY, ACLResourcePatternType.MATCH]:
  196. raise IllegalArgumentError(
  197. "pattern_type cannot be {} on a concrete ResourcePattern".format(self.pattern_type.name)
  198. )