github.com/segmentio/kafka-go@v0.4.48-0.20240318174348-3f6244eb34fd/createacls.go (about) 1 package kafka 2 3 import ( 4 "context" 5 "fmt" 6 "net" 7 "strings" 8 "time" 9 10 "github.com/segmentio/kafka-go/protocol/createacls" 11 ) 12 13 // CreateACLsRequest represents a request sent to a kafka broker to add 14 // new ACLs. 15 type CreateACLsRequest struct { 16 // Address of the kafka broker to send the request to. 17 Addr net.Addr 18 19 // List of ACL to create. 20 ACLs []ACLEntry 21 } 22 23 // CreateACLsResponse represents a response from a kafka broker to an ACL 24 // creation request. 25 type CreateACLsResponse struct { 26 // The amount of time that the broker throttled the request. 27 Throttle time.Duration 28 29 // List of errors that occurred while attempting to create 30 // the ACLs. 31 // 32 // The errors contain the kafka error code. Programs may use the standard 33 // errors.Is function to test the error against kafka error codes. 34 Errors []error 35 } 36 37 type ACLPermissionType int8 38 39 const ( 40 ACLPermissionTypeUnknown ACLPermissionType = 0 41 ACLPermissionTypeAny ACLPermissionType = 1 42 ACLPermissionTypeDeny ACLPermissionType = 2 43 ACLPermissionTypeAllow ACLPermissionType = 3 44 ) 45 46 func (apt ACLPermissionType) String() string { 47 mapping := map[ACLPermissionType]string{ 48 ACLPermissionTypeUnknown: "Unknown", 49 ACLPermissionTypeAny: "Any", 50 ACLPermissionTypeDeny: "Deny", 51 ACLPermissionTypeAllow: "Allow", 52 } 53 s, ok := mapping[apt] 54 if !ok { 55 s = mapping[ACLPermissionTypeUnknown] 56 } 57 return s 58 } 59 60 // MarshalText transforms an ACLPermissionType into its string representation. 61 func (apt ACLPermissionType) MarshalText() ([]byte, error) { 62 return []byte(apt.String()), nil 63 } 64 65 // UnmarshalText takes a string representation of the resource type and converts it to an ACLPermissionType. 66 func (apt *ACLPermissionType) UnmarshalText(text []byte) error { 67 normalized := strings.ToLower(string(text)) 68 mapping := map[string]ACLPermissionType{ 69 "unknown": ACLPermissionTypeUnknown, 70 "any": ACLPermissionTypeAny, 71 "deny": ACLPermissionTypeDeny, 72 "allow": ACLPermissionTypeAllow, 73 } 74 parsed, ok := mapping[normalized] 75 if !ok { 76 *apt = ACLPermissionTypeUnknown 77 return fmt.Errorf("cannot parse %s as an ACLPermissionType", normalized) 78 } 79 *apt = parsed 80 return nil 81 } 82 83 type ACLOperationType int8 84 85 const ( 86 ACLOperationTypeUnknown ACLOperationType = 0 87 ACLOperationTypeAny ACLOperationType = 1 88 ACLOperationTypeAll ACLOperationType = 2 89 ACLOperationTypeRead ACLOperationType = 3 90 ACLOperationTypeWrite ACLOperationType = 4 91 ACLOperationTypeCreate ACLOperationType = 5 92 ACLOperationTypeDelete ACLOperationType = 6 93 ACLOperationTypeAlter ACLOperationType = 7 94 ACLOperationTypeDescribe ACLOperationType = 8 95 ACLOperationTypeClusterAction ACLOperationType = 9 96 ACLOperationTypeDescribeConfigs ACLOperationType = 10 97 ACLOperationTypeAlterConfigs ACLOperationType = 11 98 ACLOperationTypeIdempotentWrite ACLOperationType = 12 99 ) 100 101 func (aot ACLOperationType) String() string { 102 mapping := map[ACLOperationType]string{ 103 ACLOperationTypeUnknown: "Unknown", 104 ACLOperationTypeAny: "Any", 105 ACLOperationTypeAll: "All", 106 ACLOperationTypeRead: "Read", 107 ACLOperationTypeWrite: "Write", 108 ACLOperationTypeCreate: "Create", 109 ACLOperationTypeDelete: "Delete", 110 ACLOperationTypeAlter: "Alter", 111 ACLOperationTypeDescribe: "Describe", 112 ACLOperationTypeClusterAction: "ClusterAction", 113 ACLOperationTypeDescribeConfigs: "DescribeConfigs", 114 ACLOperationTypeAlterConfigs: "AlterConfigs", 115 ACLOperationTypeIdempotentWrite: "IdempotentWrite", 116 } 117 s, ok := mapping[aot] 118 if !ok { 119 s = mapping[ACLOperationTypeUnknown] 120 } 121 return s 122 } 123 124 // MarshalText transforms an ACLOperationType into its string representation. 125 func (aot ACLOperationType) MarshalText() ([]byte, error) { 126 return []byte(aot.String()), nil 127 } 128 129 // UnmarshalText takes a string representation of the resource type and converts it to an ACLPermissionType. 130 func (aot *ACLOperationType) UnmarshalText(text []byte) error { 131 normalized := strings.ToLower(string(text)) 132 mapping := map[string]ACLOperationType{ 133 "unknown": ACLOperationTypeUnknown, 134 "any": ACLOperationTypeAny, 135 "all": ACLOperationTypeAll, 136 "read": ACLOperationTypeRead, 137 "write": ACLOperationTypeWrite, 138 "create": ACLOperationTypeCreate, 139 "delete": ACLOperationTypeDelete, 140 "alter": ACLOperationTypeAlter, 141 "describe": ACLOperationTypeDescribe, 142 "clusteraction": ACLOperationTypeClusterAction, 143 "describeconfigs": ACLOperationTypeDescribeConfigs, 144 "alterconfigs": ACLOperationTypeAlterConfigs, 145 "idempotentwrite": ACLOperationTypeIdempotentWrite, 146 } 147 parsed, ok := mapping[normalized] 148 if !ok { 149 *aot = ACLOperationTypeUnknown 150 return fmt.Errorf("cannot parse %s as an ACLOperationType", normalized) 151 } 152 *aot = parsed 153 return nil 154 155 } 156 157 type ACLEntry struct { 158 ResourceType ResourceType 159 ResourceName string 160 ResourcePatternType PatternType 161 Principal string 162 Host string 163 Operation ACLOperationType 164 PermissionType ACLPermissionType 165 } 166 167 // CreateACLs sends ACLs creation request to a kafka broker and returns the 168 // response. 169 func (c *Client) CreateACLs(ctx context.Context, req *CreateACLsRequest) (*CreateACLsResponse, error) { 170 acls := make([]createacls.RequestACLs, 0, len(req.ACLs)) 171 172 for _, acl := range req.ACLs { 173 acls = append(acls, createacls.RequestACLs{ 174 ResourceType: int8(acl.ResourceType), 175 ResourceName: acl.ResourceName, 176 ResourcePatternType: int8(acl.ResourcePatternType), 177 Principal: acl.Principal, 178 Host: acl.Host, 179 Operation: int8(acl.Operation), 180 PermissionType: int8(acl.PermissionType), 181 }) 182 } 183 184 m, err := c.roundTrip(ctx, req.Addr, &createacls.Request{ 185 Creations: acls, 186 }) 187 if err != nil { 188 return nil, fmt.Errorf("kafka.(*Client).CreateACLs: %w", err) 189 } 190 191 res := m.(*createacls.Response) 192 ret := &CreateACLsResponse{ 193 Throttle: makeDuration(res.ThrottleTimeMs), 194 Errors: make([]error, 0, len(res.Results)), 195 } 196 197 for _, t := range res.Results { 198 ret.Errors = append(ret.Errors, makeError(t.ErrorCode, t.ErrorMessage)) 199 } 200 201 return ret, nil 202 }