زبان عبارت رایج (CEL)

Common Expression Language (CEL) یک زبان بیانی همه منظوره است که برای اجرای سریع، قابل حمل و ایمن طراحی شده است. می توانید از CEL به تنهایی استفاده کنید یا آن را در یک محصول بزرگتر جاسازی کنید. CEL برای کاربردهای مختلف، از مسیریابی فراخوان‌های رویه از راه دور (RPC) گرفته تا تعریف سیاست‌های امنیتی، مناسب است. CEL قابل توسعه، مستقل از پلتفرم و برای کامپایل-یک بار/ارزیابی- بسیاری از گردش کارها بهینه شده است.

CEL به طور خاص برای ایمن بودن برای اجرای کد کاربر طراحی شده است. در حالی که فراخوانی کورکورانه eval() روی کد پایتون کاربر خطرناک است، می‌توانید با خیال راحت کد CEL کاربر را اجرا کنید. و از آنجایی که CEL از رفتاری جلوگیری می کند که عملکرد آن را کمتر کند، به طور ایمن در نانوثانیه یا میکروثانیه ارزیابی می شود. سرعت و ایمنی CEL آن را برای کاربردهای حیاتی عملکرد ایده آل می کند.

CEL عباراتی را که شبیه توابع تک خطی یا عبارات لامبدا هستند ارزیابی می کند. در حالی که CEL معمولاً برای تصمیم گیری های بولی استفاده می شود، می توانید از آن برای ساخت اشیاء پیچیده تری مانند JSON یا پیام های بافر پروتکل نیز استفاده کنید.

چرا CEL؟

بسیاری از سرویس‌ها و برنامه‌ها پیکربندی‌های اعلامی را ارزیابی می‌کنند. به عنوان مثال، کنترل دسترسی مبتنی بر نقش (RBAC) یک پیکربندی اعلامی است که یک تصمیم دسترسی را با توجه به نقش کاربر و مجموعه ای از کاربران ایجاد می کند. در حالی که تنظیمات اعلامی برای اکثر موارد کافی است، گاهی اوقات به قدرت بیان بیشتری نیاز دارید. اینجاست که CEL وارد می شود.

به عنوان نمونه ای از گسترش یک پیکربندی اعلامی با CEL، قابلیت های Google Cloud Identity and Access Management (IAM) را در نظر بگیرید. در حالی که RBAC یک مورد رایج است، IAM عبارات CEL را ارائه می دهد تا به کاربران اجازه دهد تا دامنه کمک هزینه مبتنی بر نقش را با توجه به ویژگی های پیام اولیه درخواست یا منابعی که به آنها دسترسی دارند محدود کنند. توصیف چنین شرایطی از طریق مدل داده منجر به یک سطح API پیچیده می شود که کار با آن دشوار است. درعوض، استفاده از CEL با کنترل دسترسی مبتنی بر ویژگی (ABAC) یک توسعه گویا و قدرتمند برای RBAC است.

مفاهیم اصلی CEL

در CEL، یک عبارت در برابر یک محیط کامپایل می شود. مرحله کامپایل یک درخت نحو انتزاعی (AST) در فرمت بافر پروتکل تولید می کند. عبارات کامپایل شده برای استفاده در آینده ذخیره می شوند تا ارزیابی در سریع ترین زمان ممکن حفظ شود. یک عبارت کامپایل شده را می توان با ورودی های مختلف ارزیابی کرد.

در اینجا نگاهی دقیق تر به برخی از این مفاهیم داریم.

اصطلاحات

عبارات توسط کاربران نوشته می شود. عبارات شبیه توابع تک خطی یا عبارات لامبدا هستند. امضای تابعی که ورودی را اعلام می کند خارج از عبارت CEL نوشته می شود و کتابخانه توابع موجود برای CEL به صورت خودکار وارد می شود.

به عنوان مثال، عبارت CEL زیر یک شی درخواست را می گیرد و درخواست شامل یک نشانه claims می شود. عبارت یک مقدار بولی برمی گرداند که نشان می دهد آیا نشانه claims هنوز معتبر است یا خیر.

مثال CEL عبارت برای تأیید اعتبار یک نشانه ادعا

// Check whether a JSON Web Token has expired by inspecting the 'exp' claim.
//
// Args:
//   claims - authentication claims.
//   now    - timestamp indicating the current system time.
// Returns: true if the token has expired.
//
timestamp(claims["exp"]) < now

در حالی که کاربران عبارت CEL را تعریف می کنند، سرویس ها و برنامه ها محیطی را که در آن اجرا می شود، تعریف می کنند.

محیط ها

محیط ها توسط خدمات تعریف می شوند . سرویس ها و برنامه هایی که CEL را تعبیه می کنند، محیط بیان را اعلام می کنند. محیط مجموعه ای از متغیرها و توابع است که می تواند در عبارات CEL استفاده شود.

به عنوان مثال، کد textproto زیر یک محیط حاوی request و now متغیرها را با استفاده از پیام CompileRequest از یک سرویس CEL اعلام می کند.

اعلان محیطی CEL مثال

# Format: $SOURCE_PATH/service.proto#CompileRequest
declarations {
  name: "request"
  ident {
    type { message_type: "google.rpc.context.AttributeContext.Request" }
  }
}
declarations {
  name: "now"
  ident {
    type { well_known: "TIMESTAMP" }
  }
}

اعلان‌های مبتنی بر پروتو توسط چک‌کننده نوع CEL برای اطمینان از اینکه همه ارجاع‌های شناسه و تابع در یک عبارت به درستی اعلان و استفاده می‌شوند استفاده می‌شوند.

مراحل پردازش بیان

عبارات CEL در سه مرحله پردازش می شوند:

  1. تجزیه
  2. بررسی
  3. ارزیابی کنید

رایج ترین الگوی استفاده از CEL تجزیه و بررسی عبارات در زمان پیکربندی، ذخیره AST، و سپس بازیابی و ارزیابی AST به طور مکرر در زمان اجرا است.

تصویری از مراحل پردازش CEL

عبارات در مسیرهای پیکربندی تجزیه و بررسی می شوند، ذخیره می شوند و سپس در برابر یک یا چند زمینه در مسیرهای خوانده شده ارزیابی می شوند.

CEL از یک عبارت قابل خواندن توسط انسان به یک AST با استفاده از lexer ANTLR و گرامر تجزیه کننده تجزیه می شود. فاز تجزیه یک AST مبتنی بر پروتو ساطع می کند که در آن هر گره Expr در AST حاوی یک شناسه عدد صحیح است که برای نمایه سازی به ابرداده تولید شده در طول تجزیه و بررسی استفاده می شود. فایل syntax.proto که در حین تجزیه تولید می شود، نمایش انتزاعی آن چیزی است که در شکل رشته ای عبارت تایپ شده است.

پس از تجزیه یک عبارت، آن را در برابر محیط بررسی می‌کنیم تا اطمینان حاصل شود که همه متغیرها و شناسه‌های تابع در عبارت اعلام شده‌اند و به درستی استفاده می‌شوند. type-checker یک فایل checked.proto تولید می کند که شامل متاداده نوع، متغیر و وضوح تابع است که می تواند کارایی ارزیابی را به شدت بهبود بخشد.

در نهایت، پس از تجزیه و بررسی یک عبارت، AST ذخیره شده ارزیابی می شود.

ارزیاب CEL به سه چیز نیاز دارد:

  • اتصالات تابع برای هر برنامه افزودنی سفارشی
  • اتصالات متغیر
  • یک AST برای ارزیابی

تابع و اتصالات متغیر باید با آنچه برای کامپایل AST استفاده شد مطابقت داشته باشد. هر یک از این ورودی‌ها را می‌توان در چندین ارزیابی مورد استفاده مجدد قرار داد، مانند AST که در بسیاری از مجموعه‌های اتصالات متغیر ارزیابی می‌شود، متغیرهای مشابهی که در برابر بسیاری از ASTها استفاده می‌شوند، یا اتصال‌های تابعی که در طول عمر یک فرآیند استفاده می‌شوند (یک مورد رایج).