MCPcopy Create free account
hub / github.com/cel-expr/cel-go / exercise6

Function exercise6

codelab/solution/codelab.go:240–300  ·  view source on GitHub ↗

exercise6 describes how to build proto message types within CEL. Given an input `jwt` and time `now` construct a `google.rpc.context.AttributeContext.Request` with the `time` and `auth` fields populated according to the go/api-attributes specification.

()

Source from the content-addressed store, hash-verified

238// `google.rpc.context.AttributeContext.Request` with the `time` and `auth`
239// fields populated according to the go/api-attributes specification.
240func exercise6() {
241 fmt.Println("=== Exercise 6: Building Protos ===\n")
242
243 // Construct an environment and indicate that the container for all references
244 // within the expression is `google.rpc.context.AttributeContext`.
245 requestType := &rpcpb.AttributeContext_Request{}
246 env, _ := cel.NewEnv(
247 cel.Container("google.rpc.context.AttributeContext"),
248 cel.Types(requestType),
249 cel.Variable("jwt", cel.MapType(cel.StringType, cel.DynType)),
250 cel.Variable("now", cel.TimestampType),
251 )
252
253 // Compile the `Request` message construction expression and validate that the
254 // resulting expression type matches the fully qualified message name.
255 //
256 // Note: the field names within the proto message types are not quoted as they
257 // are well-defined names composed of valid identifier characters. Also, note
258 // that when building nested proto objects, the message name needs to prefix the
259 // object construction.
260 ast := compile(env, `
261 Request{
262 auth: Auth{
263 principal: jwt.iss + '/' + jwt.sub,
264 audiences: [jwt.aud],
265 presenter: 'azp' in jwt ? jwt.azp : "",
266 claims: jwt
267 },
268 time: now
269 }`,
270 cel.ObjectType("google.rpc.context.AttributeContext.Request"))
271 program, _ := env.Program(ast)
272
273 // Construct the message. The result is a ref.Val that returns a dynamic proto message.
274 out, _, _ := eval(
275 program,
276 map[string]any{
277 "jwt": map[string]any{
278 "sub": "serviceAccount:delegate@acme.co",
279 "aud": "my-project",
280 "iss": "auth.acme.com:12350",
281 "extra_claims": map[string]string{
282 "group": "admin",
283 },
284 },
285 "now": time.Now(),
286 },
287 )
288 // Unwrap the CEL value to a proto. Make sure to use the `ConvertToNative` to convert
289 // the dynamic proto message to the concrete type expected.
290 req, err := out.ConvertToNative(reflect.TypeOf(requestType))
291 if err != nil {
292 glog.Exit(err)
293 }
294 bytes, err := prototext.Marshal(req.(proto.Message))
295 if err != nil {
296 glog.Exitf("failed to marshal proto to text: %v", req)
297 }

Callers 1

mainFunction · 0.70

Calls 8

ProgramMethod · 0.95
NewEnvFunction · 0.92
ContainerFunction · 0.92
TypesFunction · 0.92
VariableFunction · 0.92
compileFunction · 0.70
evalFunction · 0.70
ConvertToNativeMethod · 0.65

Tested by

no test coverage detected