Skip to main content

تعریف post renderer کاستوم

یکی از فیلد هایی که می‌توانید برای اپ خود تعریف کنید postRenderStarlarkScript است. اگر مایل هستید که به هر دلیلی manifest های اپلیکیشن خود را بعد از render شدن آن ها توسط دارکوب تغییر دهید، می‌توانید یک اسکریپت به زبان Starlark در این فیلد اضافه کنید.

مطالعه مستند Post Rendering در Helm برای درک بهتر مفهوم post rendering مفید است.

نحوه نگارش اسکریپت استارلارک

اسکریپت استارلارک شما باید به حالت زیر باشد.


def render(manifests):
mans = list(manifests)
// your starlark code to change mans
return mans

ورودی تابع render لیستی از منیفست هاست که هر کدام در قالب یک دیکشنری هستند.

برای درک بهتر چگونگی استفاده از این امکان به دو نمونه اسکریپت زیر توجه کنید:

  • نمونه اول: اضافه کردن یک منیفست Ingress بر اساس منیفست Service رندر شده

    def render(manifests):

    mans = list(manifests)
    service = None
    for man in mans:
    if man["kind"] == "Service":
    service = man
    break

    if service:
    ingress = {
    "apiVersion": "networking.k8s.io/v1",
    "kind": "Ingress",
    "metadata": {
    "name": service["metadata"]["name"],
    "labels": service["metadata"]["labels"],
    "annotations": {
    "cert-manager.io/cluster-issuer": "acme-prod",
    "certmanager.k8s.io/cluster-issuer": "acme-prod",
    },
    },
    "spec": {
    "rules": [
    {
    "host": "abc.com",
    "http": {
    "paths": [
    {
    "path": "/",
    "backend": {
    "service": {
    "name": service["metadata"]["name"],
    "port": {
    "name": "main"
    }
    }
    },
    "pathType": "Prefix"
    }
    ]
    }
    }
    ],
    "tls": [
    {
    "hosts": ["abc.com"],
    "secretName": "s-tls"
    }
    ]
    }
    }

    mans.append(ingress)

    return mans
  • نمونه دوم: اضافه کردن یک منیفست LogHandler به منیفست های رندر شده

    def render(manifests):
    mans = list(manifests)

    log_handler = {
    "apiVersion": "unklog.hamravesh.com/v1",
    "kind": "LogHandler",
    "metadata": {
    "name": "my-loghandler",
    },
    "spec": {
    "containers": [
    {
    "containerSelector": {
    "matchName": "main"
    },
    "sources": [
    {
    "collect": {
    "backend": "vector",
    "config": {
    "parser": {
    "@type": "none"
    },
    "tag": "my-tag"
    },
    "labels": {
    "type": "stdout"
    }
    },
    "source": "stdout"
    }
    ]
    }
    ],
    "sink": "hamravesh",
    "podSelector": {
    "matchLabels": {
    "app.kubernetes.io/instance": "pod-selector"
    }
    }
    }
    }
    mans.append(log_handler)
    return mans

توابع و مقادیر کمکی

برای تسهیل در نگارش اسکریپت استارلارک، توابع و مقادیری در اختیارتان قرار گرفته است که می‌توانید از آنها در کد خود استفاده کنید.

تابع patch

در صورت نیاز می‌توانید با استفاده از تابع patch منیفست مورد نظر خود را تغییر دهید.

امضای تابع
def patch(manifests, object_type, json_path, value, object_name=None):
...
return patched_manifests
پارامترها
  • manifests: این پارارمتر همان لیست منیفست هایی است که در وروردی تابع render دریافت می کنید.
  • object_type: در این پارامتر باید نوع object مورد نظر خود را وارد کنید. مثال : Deployment, Service, ...
  • json_path: در این پارامتر باید jsonPath استاندارد چیزی که می‌خواهید تغییرش دهید را وارد کنید.
  • value: در این پارامتر باید مقداری که مایل هستید به عنوان مقدار جدید جایگذاری شود را وارد کنید.
  • object_name: وارد شده شما انتخاب می شود. object_type در صورت تمایل می‌توانید نام آبجکت مورد نظر خود را وارد کنید. در صورت خالی گذاشتن این پارامتر اولین منیفست با
خروجی

خروجی تابع patch لیستی از منیفست هاست که patch مورد نظر شما روی آن اعمال شده است.

مثال
  •   mans = patch(mans, "Service", "spec.ports[0].name", "new_name")

تابع extract

در صورت نیاز می‌توانید با استفاده از تابع extract مقدار مورد نظر خود را از منیفست ها بگیرید.

امضای تابع
def extract(manifests, object_type, json_path, object_name=None):
...
return extracted_value
پارامترها
  • manifests: این پارامتر همان لیست منیفست هایی است که در ورودی تابع render دریافت می‌کنید.
  • object_type: در این پارامتر باید نوع object مورد نظر خود را وارد کنید. مثال : Deployment, Service, ...
  • json_path: در این پارامتر باید jsonPath استاندراد چیزی که میخواهید مقدارش را به دست آورید وارد کنید.
  • object_name: وارد شده شما انتخاب می شود. object_type در صورت تمایل می‌توانید نام آبجکت مورد نظر خود را وارد کنید. در صورت خالی گذاشتن این پارامتر اولین منیفست با
خروجی

خروجی تابع extract، بسته به json_path وارد شده، مقدار مورد نظر شماست. در صورت عدم وجود، خروجی None خواهد بود.

مثال
  •   mans = extract(mans, "Service", "metadata.labels")

دقت کنید که در jsonPath در صورت نیاز فقط از quotation استفاده کنید و از double quotation استفاده نکنید. مثال غلط: metadata.labels["app.kubernetes.io/name"] مثال صحیح: metadata.labels['app.kubernetes.io/nam']

مقادیر کمکی

می‌توانید در اسکریپت خودتان از مقدار متغیرهای کمکی RELEASE_NAME, NAMESPACE, APP_ID استفاده کنید.

مثال

def render(manifests):
mans = list(manifests)
print(RELEASE_NAME)
return mans

چگونه اسکریپتم را تست کنم؟

برای تست اسکریپت post render ای که نوشته‌اید و مشاهده منیفست‌های خروجی قبل از اعمال آن بر روی اپ، می‌توانید از اندپوینت زیر استفاده کنید. باید مقادیر APP_ID , ORGANIZATION_NAME , API_KEY را جایگذاری کنید.

curl 'https://api.console.hamravesh.ir/api/v1/darkube/apps/{APP_ID}/test_starlark_post_renderer_script/' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-H 'x-organization: {ORGANIZATION_NAME}' \
-H 'Authorization: Api-key {API_KEY}' \
--data-urlencode 'starlark_script=def post_render(manifests):
mans = list(manifests)
return mans'

در response دریافتی می‌توانید منیفست‌های حاصل را ببینید. برای تسهیل کاربری به زودی این امکان در صفحه‌ی اپ اضافه می‌شود. همچنین توابعی کمکی برای تسهیل در نوشتن این کد اضافه خواهند شد.