سرور مجازی

۱۰ مطلب با کلمه‌ی کلیدی «VPS یا سرور مجازی» ثبت شده است

  • ۰
  • ۰

 نحوه نصب و استفاده از Homebrew در لینوکس

ورود به سایت

معرفی

Homebrew یک مدیر بسته است که در ابتدا برای macOS توسعه داده شد تا به شما امکان می دهد نرم افزار رایگان و منبع باز را با استفاده از ترمینال خود نصب کنید. سیستم‌های لینوکس همگی از مدیران بسته داخلی خود مانند apt در دبیان، اوبونتو و مشتقات و dnf در Red Hat، Fedora و Rocky Linux برای نصب برنامه‌ها و ابزارها از مخازن بسته‌های قابل اعتماد و نگهداری شده استفاده می‌کنند.

با این حال، نصب همه نرم افزارها از طریق apt یا dnf همیشه عملی نیست. به عنوان مثال، برخی از زبان‌های برنامه‌نویسی ترجیح می‌دهند از مدیریت بسته‌های خود مانند پیتون پایتون یا npm Node.js برای نصب اسکریپت‌ها یا کتابخانه‌های اضافی که در حساب کاربری شما بومی‌سازی شده‌اند استفاده کنند.

اخیراً Homebrew پشتیبانی بومی برای لینوکس اضافه کرده است. در حالی که Homebrew در ابتدا برای نصب ابزارهای لینوکس در macOS ایجاد شد، بسیاری از بسته‌های Homebrew نسبت به بسته‌های مشابه موجود در مخازن لینوکس بهتر نگهداری می‌شوند یا استفاده از آنها راحت‌تر است. همچنین، از آنجایی که بسته های Homebrew فقط برای ارائه عملکرد برای هر کاربر طراحی شده اند، Homebrew می تواند در کنار مدیر بسته سیستم شما بدون ایجاد تداخل استفاده شود.

در این آموزش شما Homebrew را در محیط لینوکس نصب و استفاده می کنید. شما ابزارهای سیستم را نصب کرده و محیط پوسته خود را برای استفاده از Homebrew از رابط خط فرمان پیکربندی خواهید کرد.

پیش نیازها

  • یک سرور لینوکس یا محیط دسکتاپ، و یک کاربر غیر ریشه با امتیازات sudo.
  • گیت ابزار کنترل نسخه بر روی دستگاه شما نصب شده است.

مرحله 1 – نصب یک محیط کامپایلر

قبل از نصب Homebrew، به یک کامپایلر کار نیاز دارید تا Homebrew بتواند بسته ها را بسازد. در حالی که اکثر بسته‌ها از پیش کامپایل شده‌اند، برخی از وابستگی‌های بسته باید مستقیماً روی دستگاه شما ساخته شوند. اکثر توزیع‌های لینوکس به شما اجازه می‌دهند یک کامپایلر را با یک فرمان نصب کنید، اما به طور پیش‌فرض آن را ارائه نمی‌کنند.

در اوبونتو، می‌توانید بسته‌ای به نام build-essential نصب کنید که تمام بسته‌های مورد نیاز برای یک محیط کامپایلر مدرن و با پشتیبانی خوب را فراهم می‌کند. بسته را با apt نصب کنید:

sudo apt build-essential

در راکی لینوکس، CentOS یا سایر مشتقات RedHat، می‌توانید گروهی از بسته‌ها به نام ابزار توسعه را نصب کنید تا عملکرد کامپایلر یکسانی را ارائه دهید. بسته ها را با dnf نصب کنید:

dnf groups mark install “Development Tools”
dnf groupinstall “Development Tools”

شما می توانید با بررسی وجود دستور make در سیستم خود اطمینان حاصل کنید که یک کامپایلر در دسترس است. برای انجام این کار از دستور which استفاده کنید:

which make

 

Output

/usr/bin/make

اکنون که یک کامپایلر فعال دارید، می توانید Homebrew را نصب کنید.

مرحله 2 – نصب و راه اندازی Homebrew

برای نصب Homebrew، یک اسکریپت نصب را دانلود کرده و سپس اسکریپت را اجرا می کنید.

ابتدا اسکریپت را در دستگاه محلی خود دانلود کنید:

curl -fsSL -o install.sh https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh

این دستور از curl برای دانلود اسکریپت نصب Homebrew از مخزن Homebrew’s Git در GitHub استفاده می کند.

بیایید از طریق پرچم هایی که با دستور curl مرتبط هستند عبور کنیم:

  • پرچم -f یا –fail به پوسته می گوید که هیچ خروجی سند HTML روی خطاهای سرور ارائه نکند.
  • پرچم -s یا –silent کرل را بی صدا می کند تا متر پیشرفت را نشان ندهد و همراه با پرچم -S یا –show-error این اطمینان را ایجاد می کند که curl در صورت عدم موفقیت، پیام خطا را نشان می دهد.
  • پرچم -L یا –location به curl می گوید که تغییر مسیرها را مدیریت کند. اگر سرور گزارش دهد که صفحه درخواستی به مکان دیگری منتقل شده است، به طور خودکار درخواست را دوباره با استفاده از مکان جدید اجرا می کند.
  • سوئیچ -o نام فایل محلی را برای فایل مشخص می کند. سوئیچ -o به جای نمایش محتویات روی صفحه، محتویات را در فایلی که شما مشخص کرده اید ذخیره می کند.

قبل از اجرای اسکریپتی که از اینترنت دانلود کرده اید، باید محتویات آن را بررسی کنید تا بدانید اسکریپت چه کاری انجام می دهد. از دستور less برای بررسی اسکریپت نصب استفاده کنید تا بفهمید چه کاری انجام خواهد داد.

less install.sh

هنگامی که با محتوای اسکریپت راحت شدید، اسکریپت را با دستور bash اجرا کنید:

/bin/bash install.sh

اسکریپت نصب توضیح می دهد که چه کاری انجام می دهد و از شما می خواهد تأیید کنید که می خواهید آن را انجام دهید. این به شما امکان می دهد قبل از اینکه اجازه دهید Homebrew دقیقاً چه کاری با سیستم شما انجام دهد. همچنین تضمین می کند که پیش نیازهای لازم را قبل از ادامه آن دارید.

از شما خواسته می شود که رمز عبور خود را در طول فرآیند وارد کنید. اگر امتیازات sudo ندارید، می توانید به جای آن Ctrl+D را فشار دهید تا این دستور را دور بزنید و Homebrew با مجوزهای محدودتر نصب می شود. می توانید این گزینه را در مستندات Homebrew مرور کنید.

هر زمان که از شما خواسته شد تا نصب را تأیید کنید، حرف y را برای “بله” فشار دهید.

پس از تکمیل، خروجی نصب Homebrew شامل مراحل بعدی نیز می شود تا محیط پوسته خود را برای کار با بسته های Homebrew پیکربندی کنید. این پیکربندی تضمین می کند که ابزار Homebrew به نفع ابزارهای ارائه شده توسط مدیر بسته سیستم استفاده می شود. دستورات را از خروجی خود کپی و جایگذاری کنید تا مسیرهای پیکربندی صحیح در سیستم شما شناسایی شود. مثال زیر از bash است:

 

Output

==> Next steps:
- Run these two commands in your terminal to add Homebrew to your PATH:
    echo 'eval "$(/home/sammy/.linuxbrew/bin/brew shellenv)"' >> /home/sammy/.profile
    eval "$(/home/sammy/.linuxbrew/bin/brew shellenv)"

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

اکنون بررسی کنید که Homebrew به درستی تنظیم شده است. این دستور را اجرا کنید:

brew doctor

اگر در این زمان نیازی به به‌روزرسانی نیست، خروجی زیر را دریافت خواهید کرد:

 

Output

Your system is ready to brew.

در غیر این صورت، ممکن است برای اطمینان از به روز بودن نصب Homebrew، اخطاری برای اجرای دستور دیگری مانند به‌روزرسانی brew دریافت کنید. هر دستورالعمل روی صفحه را دنبال کنید تا پیکربندی محیط خود را قبل از حرکت به پایان برسانید.

مرحله 3 – نصب، ارتقا و حذف بسته ها

اکنون که Homebrew نصب شده است، از آن برای دانلود یک بسته استفاده کنید. دستور درخت به شما امکان می دهد یک درخت دایرکتوری گرافیکی را ببینید و از طریق Homebrew در دسترس است.

درخت را با دستور brew install نصب کنید:

brew install tree

Homebrew لیست بسته های خود را به روز می کند و سپس دستور درخت را دانلود و نصب می کند:

 

Output

. . .
==> Downloading https://ghcr.io/v2/homebrew/core/tree/manifests/2.0.2
######################################################################## 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/tree/blobs/sha256:e1d7569f6930271d694e739e93eb026aac1e8b386
==> Downloading from https://pkg-containers.githubusercontent.com/ghcr1/blobs/sha256:e1d7569f6930271d694e739
######################################################################## 100.0%
==> Pouring tree--2.0.2.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/tree/2.0.2: 8 files, 162.4KB
==> Running `brew cleanup tree`...

Homebrew فایل‌ها را به‌طور پیش‌فرض در /home/linuxbrew/.linuxbrew/bin/ نصب می‌کند، بنابراین با به‌روزرسانی‌های آینده لینوکس تداخلی ندارند. با نمایش مکان دستور با کدام دستور تأیید کنید که درخت نصب شده است:

which tree

خروجی نشان می دهد که درخت در /home/linuxbrew/.linuxbrew/bin/ قرار دارد:

 

Output

/home/linuxbrew/.linuxbrew/bin/tree

برای مشاهده نسخه، دستور درخت را اجرا کنید:

tree –version

نسخه روی صفحه چاپ می شود و نشان می دهد که نصب شده است:

 

Output

tree v2.0.2 (c) 1996 - 2022 by Steve Baker, Thomas Moore, Francesc Rocher, Florian Sesser, Kyosuke Tokoro

گاهی اوقات، شما می خواهید یک بسته موجود را ارتقا دهید. از دستور brew upgrade و به دنبال آن نام بسته استفاده کنید:

brew upgrade tree

می‌توانید برای ارتقای همه برنامه‌ها و بسته‌هایی که Homebrew مدیریت می‌کند، بدون هیچ استدلال اضافی، ارتقاء دم را اجرا کنید.

هنگامی که نسخه جدیدی را نصب می کنید، Homebrew نسخه قدیمی را در اطراف نگه می دارد. پس از مدتی، ممکن است بخواهید فضای دیسک را با حذف این کپی‌های قدیمی‌تر بازیابی کنید. برای حذف تمام نسخه‌های قدیمی نرم‌افزار مدیریت شده توسط Homebrew خود، Brew cleanup را اجرا کنید.

برای حذف بسته‌ای که دیگر از آن استفاده نمی‌کنید، از brew uninstall استفاده کنید. برای حذف دستور درخت، این دستور را اجرا کنید:

brew uninstall tree

خروجی نشان می دهد که بسته حذف شده است:

 

Output

Uninstalling /home/linuxbrew/.linuxbrew/Cellar/tree/2.0.2... (8 files, 162.4KB)

مرحله 4 – حذف نصب Homebrew

اگر دیگر نیازی به Homebrew ندارید، می توانید از اسکریپت حذف نصب آن استفاده کنید.

دانلود اسکریپت حذف با curl:

curl -fsSL -o uninstall.sh https://raw.githubusercontent.com/Homebrew/install/master/uninstall.sh

مثل همیشه، محتویات اسکریپت را با دستور less برای تایید محتویات اسکریپت مرور کنید:

less uninstall.sh

هنگامی که اسکریپت را تأیید کردید، اسکریپت را با پرچم –help اجرا کنید تا گزینه های مختلفی را که می توانید استفاده کنید مشاهده کنید:

bash uninstall.sh –help

گزینه هایی که روی صفحه نمایش داده می شوند:

 

Output

Homebrew Uninstaller
Usage: uninstall.sh [options]
    -p, --path=PATH  Sets Homebrew prefix. Defaults to /usr/local.
        --skip-cache-and-logs
                     Skips removal of HOMEBREW_CACHE and HOMEBREW_LOGS.
    -f, --force      Uninstall without prompting.
    -q, --quiet      Suppress all output.
    -d, --dry-run    Simulate uninstall but don't remove anything.
    -h, --help       Display this message.

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

bash uninstall.sh -d

اسکریپت همه چیزهایی را که حذف می کند فهرست می کند:

 

Output

Warning: This script would remove:
/home/linuxbrew/.linuxbrew/Caskroom/
/home/linuxbrew/.linuxbrew/Cellar/
/home/linuxbrew/.linuxbrew/Homebrew/
/home/linuxbrew/.linuxbrew/Homebrew/.dockerignore
/home/linuxbrew/.linuxbrew/Homebrew/.editorconfig
. . .

وقتی آماده حذف همه چیز هستید، اسکریپت را بدون هیچ پرچمی اجرا کنید:

bash uninstall.sh

این کار Homebrew و هر برنامه ای را که با آن نصب کرده اید حذف می کند.

نتیجه

در این آموزش شما Homebrew را در محیط لینوکس نصب و استفاده کردید. اکنون می توانید از Homebrew برای نصب ابزارهای خط فرمان، زبان های برنامه نویسی و سایر ابزارهایی که برای توسعه نرم افزار به آنها نیاز دارید استفاده کنید.

https://vpsgol.net/product/vps-germany/

 

https://vpsgol.net/product/vps-usa/

 

https://vpsgol.net/product/vps-france/

 

https://vpsgol.net/product/vps-canada/

 

https://vpsgol.net/product/vps-poland/

 

https://vpsgol.net/product/vps-netherlands/

 

https://vpsgol.net/product/vps-england/

برچسب‌ها:Homebrew در لینوکسVPS یا سرور مجازیاتصال به سرور مجازی لینوکسخرید سرور مجازیخرید سرور مجازی آمریکاخرید سرور مجازی فرانسهنصب کامپایلرنصب و راه اندازی Homebrew

 

  • behnam gol mohamadi
  • ۰
  • ۰

نحوه استفاده از Ansible برای نصب و راه اندازی Docker در اوبونتو 20.04

ورود به سایت

معرفی

اتوماسیون سرور در حال حاضر به دلیل ماهیت یکبار مصرف محیط های کاربردی مدرن، نقش اساسی در مدیریت سیستم ایفا می کند. ابزارهای مدیریت پیکربندی مانند Ansible معمولاً برای ساده‌سازی فرآیند نصب خودکار سرور با ایجاد رویه‌های استاندارد برای سرورهای جدید و همچنین کاهش خطای انسانی مرتبط با تنظیمات دستی استفاده می‌شوند.

Ansible یک معماری ساده ارائه می دهد که نیازی به نرم افزار خاصی برای نصب روی گره ها ندارد. همچنین مجموعه ای قوی از ویژگی ها و ماژول های داخلی را ارائه می دهد که نوشتن اسکریپت های اتوماسیون را تسهیل می کند.

این راهنما نحوه استفاده از Ansible را برای خودکارسازی مراحل موجود در راهنمای ما در مورد نحوه نصب و استفاده از Docker در اوبونتو 20.04 توضیح می دهد. Docker برنامه‌ای است که فرآیند مدیریت کانتینرها، فرآیندهای جدا شده از منابع را که به روشی مشابه ماشین‌های مجازی عمل می‌کنند، اما قابل حمل‌تر، منابع دوست‌تر و بیشتر به سیستم عامل میزبان وابسته هستند، ساده می‌کند.

پیش نیازها

برای اجرای تنظیمات خودکار ارائه شده توسط playbook در این راهنما، به موارد زیر نیاز دارید:

  • یک گره کنترلی Ansible: یک ماشین اوبونتو 20.04 با Ansible نصب و پیکربندی شده است تا با استفاده از کلیدهای SSH به میزبان Ansible شما متصل شود. اطمینان حاصل کنید که گره کنترل دارای یک کاربر معمولی با مجوزهای sudo و فایروال فعال است، همانطور که در راهنمای راه اندازی سرور اولیه ما توضیح داده شده است.
  • یک یا چند میزبان Ansible: یک یا چند سرور اوبونتو 20.04 راه دور که قبلاً طبق راهنمای نحوه استفاده از Ansible برای خودکارسازی تنظیمات اولیه سرور در اوبونتو 20.04 تنظیم شده است.

این کتاب بازی چه کاری انجام می دهد؟

این کتاب بازی Ansible جایگزینی برای اجرای دستی روشی است که در راهنمای ما در مورد نحوه نصب و استفاده از Docker در اوبونتو 20.04 بیان شده است. Playbook خود را یک بار تنظیم کنید و بعد از هر نصب از آن استفاده کنید.

اجرای این کتاب بازی، اقدامات زیر را روی میزبان های Ansible شما انجام می دهد:

  • aptitude را نصب کنید که توسط Ansible به عنوان جایگزینی برای مدیر بسته apt ترجیح داده می شود.
  • بسته های سیستمی مورد نیاز را نصب کنید.
  • کلید Docker GPG APT را نصب کنید.
  • مخزن رسمی Docker را به منابع apt اضافه کنید.
  • Docker را نصب کنید.
  • ماژول Python Docker را از طریق پیپ نصب کنید.
  • تصویر پیش‌فرض مشخص‌شده توسط default_container_image را از Docker Hub بکشید.
  • تعداد کانتینرهای تعریف شده توسط متغیر container_count را ایجاد کنید، هر کدام با استفاده از تصویر تعریف شده توسط default_container_image، و دستور تعریف شده در default_container_command را در هر کانتینر جدید اجرا کنید.

پس از اتمام اجرای کتاب بازی، تعدادی کانتینر بر اساس گزینه هایی که در متغیرهای پیکربندی خود تعریف کرده اید ایجاد خواهید کرد.

برای شروع، وارد یک کاربر دارای sudo در سرور گره کنترل Ansible خود شوید.

مرحله 1 – آماده کردن Playbook خود

فایل playbook.yml جایی است که تمام وظایف شما در آن تعریف می شود. یک کار کوچکترین واحد عملی است که می توانید با استفاده از کتاب بازی Ansible به طور خودکار انجام دهید. اما ابتدا، فایل playbook خود را با استفاده از ویرایشگر متن دلخواه خود ایجاد کنید:

nano playbook.yml

با این کار یک فایل YAML خالی باز می شود. قبل از اضافه کردن وظایف به کتاب بازی خود، با افزودن موارد زیر شروع کنید:

playbook.yml

---
- hosts: all
  become: true
  vars:
    container_count: 4
    default_container_name: docker
    default_container_image: ubuntu
    default_container_command: sleep 1

تقریباً هر کتاب بازی که با آن روبرو می شوید با اعلان هایی مشابه این شروع می شود. hosts اعلام می کند که گره کنترل Ansible کدام سرورها را با این کتاب بازی هدف قرار می دهد. تبدیل وضعیت می کند که آیا همه دستورات با امتیازات ریشه افزایش یافته انجام می شوند یا خیر.

vars به شما امکان می دهد داده ها را در متغیرها ذخیره کنید. اگر تصمیم به تغییر این موارد در آینده دارید، فقط باید این خطوط را در فایل خود ویرایش کنید. در اینجا توضیح مختصری در مورد هر متغیر آورده شده است:

  • container_count: تعداد کانتینرهایی که باید ایجاد شوند.
  • default_container_name: نام کانتینر پیش‌فرض.
  • default_container_image: تصویر پیش‌فرض Docker برای استفاده در هنگام ایجاد کانتینرها.
  • default_container_command: دستور پیش فرض برای اجرا در کانتینرهای جدید.

مرحله 2 – افزودن وظایف نصب بسته ها به Playbook خود

به طور پیش فرض، وظایف به صورت همزمان توسط Ansible به ترتیب از بالا به پایین در کتاب بازی شما اجرا می شوند. این بدان معناست که ترتیب کارها مهم است، و شما می توانید با خیال راحت فرض کنید که اجرای یک کار قبل از شروع کار بعدی به پایان می رسد.

همه وظایف موجود در این کتاب بازی می توانند به تنهایی بایستند و مجدداً در سایر کتاب های بازی شما مورد استفاده قرار گیرند.

اولین وظایف خود یعنی نصب aptitude، ابزاری برای ارتباط با مدیر بسته لینوکس و نصب بسته های سیستم مورد نیاز را اضافه کنید. Ansible اطمینان حاصل می کند که این بسته ها همیشه بر روی سرور شما نصب می شوند:

playbook.yml

  tasks:
    - name: Install aptitude
      apt:
        name: aptitude
        state: latest
        update_cache: true

    - name: Install required system packages
      apt:
        pkg:
          - apt-transport-https
          - ca-certificates
          - curl
          - software-properties-common
          - python3-pip
          - virtualenv
          - python3-setuptools
        state: latest
        update_cache: true

در اینجا، شما از ماژول داخلی apt Ansible برای هدایت Ansible برای نصب بسته های خود استفاده می کنید. ماژول ها در Ansible میانبرهایی برای اجرای عملیاتی هستند که در غیر این صورت باید به عنوان دستورات bash خام اجرا می شدند. اگر aptitude در دسترس نباشد، Ansible با خیال راحت به apt برای نصب بسته ها باز می گردد، اما Ansible از لحاظ تاریخی استعداد را ترجیح داده است.

می توانید بسته ها را به دلخواه خود اضافه یا حذف کنید. این اطمینان حاصل می کند که همه بسته ها نه تنها موجود هستند، بلکه در آخرین نسخه هستند و پس از فراخوانی به روز رسانی با apt انجام می شود.

مرحله 3 – افزودن وظایف نصب Docker به Playbook خود

وظیفه شما آخرین نسخه Docker را از مخزن رسمی نصب می کند. کلید Docker GPG برای تأیید دانلود اضافه می شود، مخزن رسمی به عنوان منبع بسته جدید اضافه می شود و Docker نصب می شود. علاوه بر این، ماژول داکر برای پایتون نیز نصب خواهد شد:

playbook.yml

    - name: Add Docker GPG apt Key
      apt_key:
        url: https://download.docker.com/linux/ubuntu/gpg
        state: present

    - name: Add Docker Repository
      apt_repository:
        repo: deb https://download.docker.com/linux/ubuntu focal stable
        state: present

    - name: Update apt and install docker-ce
      apt:
        name: docker-ce
        state: latest
        update_cache: true

    - name: Install Docker Module for Python
      pip:
        name: docker

خواهید دید که ماژول‌های Ansible داخلی apt_key و apt_repository ابتدا به آدرس‌های اینترنتی صحیح اشاره می‌کنند، سپس وظیفه دارند از وجود آنها اطمینان حاصل کنند. این امکان نصب آخرین نسخه Docker را به همراه استفاده از پیپ برای نصب ماژول برای پایتون فراهم می کند.

مرحله 4 – افزودن Docker Image و وظایف Container به Playbook خود

ایجاد واقعی کانتینرهای Docker شما از اینجا با کشیدن تصویر Docker مورد نظر شما شروع می شود. به طور پیش فرض، این تصاویر از داکر هاب رسمی می آیند. با استفاده از این تصویر، کانتینرها مطابق با مشخصات تعیین شده توسط متغیرهای اعلام شده در بالای کتاب بازی شما ایجاد می شوند:

playbook.yml

    - name: Pull default Docker image
      community.docker.docker_image:
        name: "{{ default_container_image }}"
        source: pull

    - name: Create default containers
      community.docker.docker_container:
        name: "{{ default_container_name }}{{ item }}"
        image: "{{ default_container_image }}"
        command: "{{ default_container_command }}"
        state: present
      with_sequence: count={{ container_count }}

از docker_image برای کشیدن تصویر Docker که می‌خواهید به عنوان پایه کانتینرهای خود استفاده کنید استفاده می‌شود. docker_container به شما اجازه می دهد تا مشخصات کانتینرهایی را که ایجاد می کنید، به همراه دستوری که می خواهید آنها را ارسال کنید، مشخص کنید.

with_sequence روش Ansible برای ایجاد یک حلقه است و در این حالت ایجاد کانتینرهای شما را با توجه به تعداد تعیین شده شما حلقه می کند. این یک حلقه شمارش اولیه است، بنابراین متغیر آیتم در اینجا عددی را ارائه می دهد که تکرار حلقه فعلی را نشان می دهد. این شماره در اینجا برای نامگذاری ظروف شما استفاده می شود.

مرحله 5 – کتاب راهنمای کامل خود را مرور کنید

کتاب بازی شما باید تقریباً شبیه شکل زیر باشد، با تفاوت های جزئی بسته به سفارشی سازی های شما:

playbook.yml

---
- hosts: all
  become: true
  vars:
    container_count: 4
    default_container_name: docker
    default_container_image: ubuntu
    default_container_command: sleep 1d

  tasks:
    - name: Install aptitude
      apt:
        name: aptitude
        state: latest
        update_cache: true

    - name: Install required system packages
      apt:
        pkg:
          - apt-transport-https
          - ca-certificates
          - curl
          - software-properties-common
          - python3-pip
          - virtualenv
          - python3-setuptools
        state: latest
        update_cache: true

    - name: Add Docker GPG apt Key
      apt_key:
        url: https://download.docker.com/linux/ubuntu/gpg
        state: present

    - name: Add Docker Repository
      apt_repository:
        repo: deb https://download.docker.com/linux/ubuntu focal stable
        state: present

    - name: Update apt and install docker-ce
      apt:
        name: docker-ce
        state: latest
        update_cache: true

    - name: Install Docker Module for Python
      pip:
        name: docker

    - name: Pull default Docker image
      community.docker.docker_image:
        name: "{{ default_container_image }}"
        source: pull

    - name: Create default containers
      community.docker.docker_container:
        name: "{{ default_container_name }}{{ item }}"
        image: "{{ default_container_image }}"
        command: "{{ default_container_command }}"
        state: present
      with_sequence: count={{ container_count }}

با خیال راحت این کتاب راهنما را طوری تغییر دهید که مطابق با نیازهای فردی شما در جریان کار خود باشد. برای مثال، می‌توانید از ماژول docker_image برای فشار دادن تصاویر به Docker Hub یا ماژول docker_container برای راه‌اندازی شبکه‌های کانتینری استفاده کنید.

مرحله 6 – اجرای Playbook خود

اکنون آماده اجرای این کتاب بازی در یک یا چند سرور هستید. اکثر کتاب‌های پخش به‌طور پیش‌فرض پیکربندی شده‌اند که در هر سرور موجود در فهرست شما اجرا شوند، اما شما این بار سرور خود را مشخص می‌کنید.

برای اجرای playbook فقط در server1 که به صورت sammy متصل می شود، می توانید از دستور زیر استفاده کنید:

ansible-playbook playbook.yml -l server1 -u sammy

پرچم -l سرور شما را مشخص می‌کند و پرچم -u مشخص می‌کند که کدام کاربر در سرور راه دور وارد شود. خروجی مشابه این دریافت خواهید کرد:

این نشان می دهد که راه اندازی سرور شما کامل شده است! خروجی شما نباید دقیقاً یکسان باشد، اما مهم این است که هیچ شکستی نداشته باشید.

پس از اتمام اجرا، از طریق SSH به سروری که توسط Ansible ارائه شده است وارد شوید تا بررسی کنید که آیا کانتینرها با موفقیت ایجاد شده اند یا خیر.

وارد سرور راه دور با:

ssh sammy@your_remote_server_ip

و ظروف Docker خود را در سرور راه دور فهرست کنید:

sudo docker ps -a

شما باید خروجی مشابه این را ببینید:

 

Output

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
a3fe9bfb89cf        ubuntu              "sleep 1d"          5 minutes ago       Created                                 docker4
8799c16cde1e        ubuntu              "sleep 1d"          5 minutes ago       Created                                 docker3
ad0c2123b183        ubuntu              "sleep 1d"          5 minutes ago       Created                                 docker2
b9350916ffd8        ubuntu              "sleep 1d"          5 minutes ago       Created                                 docker1

این بدان معناست که کانتینرهای تعریف شده در playbook با موفقیت ایجاد شده اند. از آنجایی که این آخرین کار در playbook بود، همچنین تأیید می کند که playbook به طور کامل در این سرور اجرا شده است.

نتیجه

تنظیم خودکار زیرساخت شما نه تنها می تواند در وقت شما صرفه جویی کند، بلکه کمک می کند تا اطمینان حاصل شود که سرورهای شما از یک پیکربندی استاندارد پیروی می کنند که می تواند مطابق با نیازهای شما سفارشی شود. با ماهیت توزیع شده برنامه های مدرن و نیاز به سازگاری بین محیط های مرحله بندی مختلف، اتوماسیون مانند این به یک جزء اصلی در فرآیندهای توسعه بسیاری از تیم ها تبدیل شده است.

در این راهنما، نحوه استفاده از Ansible برای خودکار کردن فرآیند نصب و راه‌اندازی Docker در یک سرور راه دور را نشان دادید. از آنجایی که هر فرد معمولاً هنگام کار با کانتینر نیازهای متفاوتی دارد، توصیه می کنیم برای اطلاعات بیشتر و موارد استفاده از ماژول docker_container Ansible، اسناد رسمی Ansible را بررسی کنید.

 

 

https://vpsgol.net/product/vps-germany/

 

https://vpsgol.net/product/vps-usa/

 

https://vpsgol.net/product/vps-france/

 

https://vpsgol.net/product/vps-canada/

 

https://vpsgol.net/product/vps-poland/

 

https://vpsgol.net/product/vps-netherlands/

 

https://vpsgol.net/product/vps-england/

برچسب‌ها:VPS یا سرور مجازیآماده کردن Playbookافزودن Docker Imageانواع سرور مجازیاوبونتو 20.04ایجاد سرور مجازیبه روز رسانی سرورخرید سرور مجازیکتاب بازی Ansible

  • behnam gol mohamadi
  • ۰
  • ۰

نحوه نصب Hadoop در حالت مستقل در اوبونتو 20.04

ورود به سایت

معرفی

Hadoop یک چارچوب برنامه نویسی مبتنی بر جاوا است که از پردازش و ذخیره مجموعه داده های بسیار بزرگ در مجموعه ای از ماشین های ارزان قیمت پشتیبانی می کند. این اولین پروژه بزرگ منبع باز در زمینه بازی کلان داده بود و توسط بنیاد نرم افزار آپاچی حمایت می شود.

Hadoop از چهار لایه اصلی تشکیل شده است:

Hadoop Common مجموعه ای از ابزارها و کتابخانه هایی است که از ماژول های دیگر Hadoop پشتیبانی می کند.
HDFS که مخفف Hadoop Distributed File System است، مسئول ماندگاری داده ها روی دیسک است.
YARN، مخفف Yet Another Resource Negotiator، «سیستم عامل» برای HDFS است.
MapReduce مدل پردازش اصلی برای خوشه‌های Hadoop است. کار را در خوشه یا نقشه توزیع می کند، سپس نتایج را از گره ها به یک پاسخ به یک پرس و جو سازماندهی و کاهش می دهد. بسیاری از مدل‌های پردازشی دیگر برای نسخه 3.x Hadoop در دسترس هستند.
راه اندازی خوشه های Hadoop نسبتاً پیچیده است، بنابراین پروژه شامل یک حالت مستقل است که برای یادگیری در مورد Hadoop، انجام عملیات ساده و اشکال زدایی مناسب است.

در این آموزش، Hadoop را در حالت مستقل نصب می‌کنید و یکی از نمونه‌های برنامه MapReduce را اجرا می‌کنید تا نصب را تأیید کنید.

پیش نیازها

برای دنبال کردن این آموزش، شما نیاز دارید:

سرور اوبونتو 20.04 با کاربر غیر ریشه با امتیازات sudo: می‌توانید در راهنمای راه‌اندازی سرور اولیه با اوبونتو 20.04 درباره نحوه راه‌اندازی کاربری با این امتیازات بیشتر بدانید.
همچنین ممکن است دوست داشته باشید نگاهی به مقدمه ای بر مفاهیم و اصطلاحات کلان داده یا مقدمه ای بر هادوپ بیندازید.

پس از تکمیل پیش نیازها، برای شروع به عنوان کاربر sudo خود وارد شوید.

مرحله 1 – نصب جاوا

برای شروع، لیست بسته ما را به روز می کنید و OpenJDK، کیت توسعه پیش فرض جاوا را در اوبونتو 20.04 نصب می کنید:

sudo apt update
sudo apt install default-jdk

پس از اتمام نصب، بیایید نسخه را بررسی کنیم.

java -version

 

Output

openjdk version "11.0.13" 2021-10-19
OpenJDK Runtime Environment (build 11.0.13+8-Ubuntu-0ubuntu1.20.04)
OpenJDK 64-Bit Server VM (build 11.0.13+8-Ubuntu-0ubuntu1.20.04, mixed mode, sharing)

این خروجی تأیید می کند که OpenJDK با موفقیت نصب شده است.

مرحله 2 – نصب Hadoop

با جاوا در جای خود، از صفحه انتشارات Apache Hadoop دیدن خواهید کرد تا آخرین نسخه پایدار را بیابید.

برای نسخه ای که می خواهید نصب کنید به باینری بروید. در این راهنما شما Hadoop 3.3.1 را نصب خواهید کرد، اما می توانید شماره نسخه های موجود در این راهنما را با یکی از دلخواه خود جایگزین کنید.

در صفحه بعد، کلیک راست کرده و پیوند را به باینری انتشار کپی کنید.

در سرور، از wget برای واکشی آن استفاده خواهید کرد:

wget https://dlcdn.apache.org/hadoop/common/hadoop-3.3.1/hadoop-3.3.1.tar.gz

برای اینکه مطمئن شوید فایلی که دانلود کرده اید تغییر نکرده است، یک بررسی سریع با استفاده از SHA-512 یا الگوریتم هش ایمن 512 انجام خواهید داد. به صفحه انتشار بازگردید، سپس کلیک راست کرده و پیوند را در کپی کنید. فایل چک‌سوم برای نسخه باینری که دانلود کرده‌اید:

باز هم از wget در سرور ما برای دانلود فایل استفاده خواهید کرد:

wget https://downloads.apache.org/hadoop/common/hadoop-3.3.1/hadoop-3.3.1.tar.gz.sha512

سپس تأیید را اجرا کنید:

shasum -a 512 hadoop-3.3.1.tar.gz

 

Output

2fd0bf74852c797dc864f373ec82ffaa1e98706b309b30d1effa91ac399b477e1accc1ee74d4ccbb1db7da1c5c541b72e4a834f131a99f2814b030fbd043df66  hadoop-3.3.1.tar.gz

این مقدار را با مقدار SHA-512 در فایل .sha512 مقایسه کنید:

cat hadoop-3.3.1.tar.gz.sha512

~/hadoop-3.3.1.tar.gz.sha512

...
SHA512 (hadoop-3.3.1.tar.gz) = 2fd0bf74852c797dc864f373ec82ffaa1e98706b309b30d1effa91ac399b477e1accc1ee74d4ccbb1db7da1c5c541b72e4a834f131a99f2814b030fbd043df66
...

خروجی دستوری که در برابر فایلی که از mirror دانلود کرده اید اجرا می کنید باید با مقدار فایلی که از apache.org دانلود کرده اید مطابقت داشته باشد.

اکنون که تأیید کرده اید که فایل خراب یا تغییر نکرده است، می توانید آن را استخراج کنید:

tar -xzvf hadoop-3.3.1.tar.gz

خروجی دستوری که در برابر فایلی که از mirror دانلود کرده اید اجرا می کنید باید با مقدار فایلی که از apache.org دانلود کرده اید مطابقت داشته باشد.

اکنون که تأیید کرده اید که فایل خراب یا تغییر نکرده است، می توانید آن را استخراج کنید:

sudo mv hadoop-3.3.1 /usr/local/hadoop

با نصب نرم افزار، آماده پیکربندی محیط آن هستید.

مرحله 3 – پیکربندی جاوا خانه Hadoop

Hadoop نیاز دارد که مسیر جاوا را به عنوان یک متغیر محیطی یا در فایل پیکربندی Hadoop تنظیم کنید.

مسیر جاوا /usr/bin/java یک پیوند نمادین به /etc/alternatives/java است که به نوبه خود یک پیوند نمادین به باینری پیش فرض جاوا است. شما از readlink با پرچم -f برای دنبال کردن هر پیوند نمادین در هر قسمت از مسیر، به صورت بازگشتی استفاده خواهید کرد. سپس، از sed برای برش bin/java از خروجی استفاده خواهید کرد تا مقدار صحیح JAVA_HOME را به ما بدهید.

برای یافتن مسیر پیش فرض جاوا

readlink -f /usr/bin/java | sed “s:bin/java::”

 

Output

/usr/lib/jvm/java-11-openjdk-amd64/

می‌توانید این خروجی را برای تنظیم خانه جاوای Hadoop روی این نسخه خاص کپی کنید، که تضمین می‌کند اگر جاوا پیش‌فرض تغییر کند، این مقدار تغییر نخواهد کرد. همچنین، می‌توانید از دستور readlink به صورت پویا در فایل استفاده کنید تا Hadoop به‌طور خودکار از هر نسخه جاوا که به‌عنوان پیش‌فرض سیستم تنظیم شده است استفاده کند.

برای شروع، hadoop-env.sh را باز کنید:

sudo nano /usr/local/hadoop/etc/hadoop/hadoop-env.sh

سپس با انتخاب یکی از گزینه های زیر فایل را تغییر دهید:

گزینه 1: یک مقدار استاتیک تنظیم کنید

/usr/local/hadoop/etc/hadoop/hadoop-env.sh

 . . .
#export JAVA_HOME=
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64/
 . . .

گزینه 2: از Readlink برای تنظیم ارزش به صورت پویا استفاده کنید

/usr/local/hadoop/etc/hadoop/hadoop-env.sh

 . . .
#export JAVA_HOME=
export JAVA_HOME=$(readlink -f /usr/bin/java | sed "s:bin/java::")
 . . .

اگر در یافتن این خطوط مشکل دارید، از CTRL+W برای جستجوی سریع متن استفاده کنید. پس از اتمام کار، با CTRL+X خارج شوید و فایل خود را ذخیره کنید.

مرحله 4 – اجرای Hadoop

اکنون باید بتوانید Hadoop را اجرا کنید:

/usr/local/hadoop/bin/hadoop

 

Output

Usage: hadoop [OPTIONS] SUBCOMMAND [SUBCOMMAND OPTIONS]
 or    hadoop [OPTIONS] CLASSNAME [CLASSNAME OPTIONS]
  where CLASSNAME is a user-provided Java class

  OPTIONS is none or any of:

--config dir                     Hadoop config directory
--debug                          turn on shell script debug mode
--help                           usage information
buildpaths                       attempt to add class files from build tree
hostnames list[,of,host,names]   hosts to use in slave mode
hosts filename                   list of hosts to use in slave mode
loglevel level                   set the log4j level for this command
workers                          turn on worker mode

  SUBCOMMAND is one of:
. . .

این خروجی به این معنی است که Hadoop را با موفقیت پیکربندی کرده اید تا در حالت مستقل اجرا شود.

با اجرای نمونه برنامه MapReduce که با آن ارسال می شود، مطمئن خواهید شد که Hadoop به درستی کار می کند. برای انجام این کار، یک دایرکتوری به نام input در فهرست اصلی خود ایجاد کنید و فایل های پیکربندی Hadoop را در آن کپی کنید تا از آن فایل ها به عنوان داده استفاده کنید.

mkdir ~/input
cp /usr/local/hadoop/etc/hadoop/*.xml ~/input

در مرحله بعد، می توانید از دستور زیر برای اجرای برنامه MapReduce hadoop-mapreduce-examples، یک بایگانی جاوا با چندین گزینه استفاده کنید:

/usr/local/hadoop/bin/hadoop jar /usr/local/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.1.jar grep ~/input ~/grep_example ‘allowed[.]*’

این برنامه grep را فراخوانی می کند، یکی از نمونه های متعدد موجود در نمونه های hadoop-mapreduce، و به دنبال آن دایرکتوری ورودی، ورودی و دایرکتوری خروجی grep_example. برنامه MapReduce grep مطابقت های یک کلمه تحت اللفظی یا عبارت منظم را می شمارد. در نهایت، عبارت منظم allow[.]* برای یافتن رخدادهای کلمه مجاز در داخل یا در انتهای یک جمله اعلانی داده می شود. این عبارت به حروف کوچک و بزرگ حساس است، بنابراین اگر در ابتدای جمله با حروف بزرگ نوشته می شد، کلمه ای را پیدا نمی کنید.

هنگامی که کار تکمیل می شود، خلاصه ای از آنچه پردازش شده و خطاهایی که با آن مواجه شده است ارائه می دهد، اما این شامل نتایج واقعی نیست.

 

Output

 . . .
   File System Counters
        FILE: Number of bytes read=1200956
        FILE: Number of bytes written=3656025
        FILE: Number of read operations=0
        FILE: Number of large read operations=0
        FILE: Number of write operations=0
    Map-Reduce Framework
        Map input records=2
        Map output records=2
        Map output bytes=33
        Map output materialized bytes=43
        Input split bytes=114
        Combine input records=0
        Combine output records=0
        Reduce input groups=2
        Reduce shuffle bytes=43
        Reduce input records=2
        Reduce output records=2
        Spilled Records=4
        Shuffled Maps =1
        Failed Shuffles=0
        Merged Map outputs=1
        GC time elapsed (ms)=41
        Total committed heap usage (bytes)=403800064
    Shuffle Errors
        BAD_ID=0
        CONNECTION=0
        IO_ERROR=0
        WRONG_LENGTH=0
        WRONG_MAP=0
        WRONG_REDUCE=0
    File Input Format Counters
        Bytes Read=147
    File Output Format Counters
        Bytes Written=34

نتایج در دایرکتوری خروجی ذخیره می شوند و با اجرای cat در فهرست خروجی قابل بررسی هستند:

cat ~/grep_example/*

 

Output

22    allowed.
1    allowed

وظیفه MapReduce 19 مورد از کلمه مجاز را پیدا کرد و سپس یک نقطه و یک مورد در جایی که نبود. اجرای برنامه نمونه تأیید می کند که نصب مستقل ما به درستی کار می کند و کاربران غیرمجاز در سیستم می توانند Hadoop را برای کاوش یا اشکال زدایی اجرا کنند.

نتیجه

در این آموزش، Hadoop را در حالت مستقل نصب کرده اید و با اجرای یک برنامه نمونه ارائه شده آن را تأیید کرده اید.

 

 

https://vpsgol.net/product/vps-germany/

 

https://vpsgol.net/product/vps-usa/

 

https://vpsgol.net/product/vps-france/

 

https://vpsgol.net/product/vps-canada/

 

https://vpsgol.net/product/vps-poland/

 

https://vpsgol.net/product/vps-netherlands/

 

https://vpsgol.net/product/vps-england/ 

برچسب‌ها:VPS یا سرور مجازیاتصال به سرور مجازی لینوکساجرای Hadoopپیکربندی جاواخرید سرور مجازیخرید سرور مجازی آمریکاراه اندازی اولیه سرورنصب Hadoopنصب سرور اوبونتو 20.04

  • behnam gol mohamadi
  • ۰
  • ۰

نحوه استفاده از تاریخ و زمان در Go

ورود به سایت

معرفی

نرم افزار به گونه ای طراحی شده است که انجام کار را آسان تر می کند، و برای بسیاری از افراد، شامل تعامل با تاریخ و زمان می شود. مقادیر تاریخ و زمان در همه جا در نرم افزار مدرن نشان داده می شود. به عنوان مثال، پیگیری زمان نیاز خودرو به خدمات و اطلاع دادن به مالک، پیگیری تغییرات در پایگاه داده برای ایجاد گزارش حسابرسی، یا فقط مقایسه یک زمان با زمان دیگر برای تعیین مدت زمان طول کشیده یک فرآیند. بنابراین، بازیابی زمان جاری، دستکاری مقادیر زمان برای استخراج اطلاعات از آنها و نمایش آنها به کاربران در قالبی قابل فهم از ویژگی های ضروری یک برنامه کاربردی است.

در این آموزش، شما یک برنامه Go ایجاد می‌کنید تا زمان محلی فعلی رایانه خود را دریافت کنید، سپس آن را با فرمتی که برای مردم راحت‌تر خوانده شود، روی صفحه چاپ کنید. در مرحله بعد، رشته ای را برای استخراج اطلاعات تاریخ و زمان تفسیر می کنید. شما همچنین مقادیر تاریخ و زمان را بین دو منطقه زمانی ترجمه می‌کنید، همچنین مقادیر زمانی را برای تعیین فاصله بین دو زمان اضافه یا کم می‌کنید.

پیش نیازها

Go نسخه 1.16 یا بالاتر نصب شده است، که می توانید با دنبال کردن سری ما، نحوه نصب و راه اندازی یک محیط برنامه نویسی محلی برای Go، این کار را انجام دهید.

دریافت زمان فعلی

در این بخش، زمان فعلی را با استفاده از بسته زمانی Go دریافت خواهید کرد. بسته زمانی در کتابخانه استاندارد Go انواع توابع مربوط به تاریخ و زمان را ارائه می‌کند و می‌تواند برای نمایش یک نقطه خاص در زمان با استفاده از نوع time.Time استفاده شود. علاوه بر زمان و تاریخ، می‌تواند اطلاعاتی در مورد منطقه زمانی که تاریخ و زمان نمایش داده شده در آن قرار دارد نیز در خود جای دهد.

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

دایرکتوری پروژه ها را بسازید و به آن بروید:

mkdir projects

cd projects

هنگامی که فهرست پروژه خود را ایجاد کردید، یک فایل main.go را با استفاده از nano یا ویرایشگر دلخواه خود باز کنید:

nano main.go

در فایل main.go، یک تابع اصلی اضافه کنید که زمان جاری را دریافت کرده و آن را چاپ می کند:

projects/datetime/main.go

package main

import (
	"fmt"
	"time"
)

func main() {
	currentTime := time.Now()
	fmt.Println("The time is", currentTime)
}

در این برنامه تابع time.Now از بسته زمان برای دریافت زمان محلی فعلی به عنوان مقدار time.Time استفاده می شود و سپس آن را در متغیر currentTime ذخیره می کند. هنگامی که در متغیر ذخیره شد، تابع fmt.Println، CurrentTime را با استفاده از فرمت خروجی رشته پیش فرض time.Time روی صفحه چاپ می کند.

برنامه را با استفاده از go run با فایل main.go اجرا کنید:

go run main.go

خروجی که تاریخ و زمان فعلی شما را نشان می دهد مشابه این خواهد بود:

 

Output

The time is 2021-08-15 14:30:45.0000001 -0500 CDT m=+0.000066626

خروجی تاریخ و زمان فعلی شما را نشان می دهد که با مثال متفاوت است. علاوه بر این، منطقه زمانی که مشاهده می کنید (-0500 CDT در این خروجی) احتمالاً متفاوت خواهد بود، زیرا time.Now() زمان را در منطقه زمانی محلی برمی گرداند.

همچنین ممکن است متوجه یک مقدار m= در خروجی خود شوید. این مقدار ساعت یکنواخت است و به صورت داخلی توسط Go هنگام اندازه گیری تفاوت در زمان استفاده می شود. ساعت یکنواخت برای جبران هرگونه تغییر احتمالی در تاریخ و زمان ساعت سیستم کامپیوتر در حین اجرای برنامه طراحی شده است. با استفاده از ساعت یکنواخت، یک مقدار time.Now در مقایسه با زمان. اکنون مقدار پنج دقیقه بعد همچنان به نتیجه صحیح ختم می شود (فاصله پنج دقیقه)، حتی اگر ساعت سیستم برای رایانه یک ساعت به جلو تغییر کند. یا در طی آن فاصله پنج دقیقه ای به عقب برگردید. برای کد یا مثال‌های موجود در این آموزش، نیازی به درک کامل آن ندارید، اما اگر می‌خواهید درباره ساعت‌های یکنواخت و نحوه استفاده Go از آن‌ها بیشتر بدانید، بخش ساعت‌های یکنواخت در مستندات بسته زمانی جزئیات بیشتری را ارائه می‌دهد.

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

خوشبختانه، نوع time.Time شامل روش های مختلفی برای به دست آوردن قسمت های خاصی از تاریخ یا ساعت مورد نظر شما است. به عنوان مثال، اگر فقط می‌خواهید بخش سال متغیر currentTime را بدانید، می‌توانید از روش Year استفاده کنید یا ساعت جاری را با استفاده از روش Hour دریافت کنید.

فایل main.go خود را دوباره باز کنید و چند روش time.Time را به خروجی خود اضافه کنید تا ببینید چه چیزی تولید می کنند:

projects/datetime/main.go

...

func main() {
	currentTime := time.Now()
	fmt.Println("The time is", currentTime)
	
	fmt.Println("The year is", currentTime.Year())
	fmt.Println("The month is", currentTime.Month())
	fmt.Println("The day is", currentTime.Day())
	fmt.Println("The hour is", currentTime.Hour())
	fmt.Println("The minute is", currentTime.Hour())
	fmt.Println("The second is", currentTime.Second())
}

سپس با استفاده از go run دوباره برنامه خود را اجرا کنید:

go run main.go

خروجی شبیه به این خواهد بود:

 

Output

The time is 2021-08-15 14:30:45.0000001 -0500 CDT m=+0.000066626
The year is 2021
The month is August
The day is 15
The hour is 14
The minute is 14
The second is 45

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

اکنون، فایل main.go را دوباره در برنامه خود به‌روزرسانی کنید و خروجی‌های تابع مختلف را با یک فراخوانی تابع به fmt.Printf جایگزین کنید، بنابراین می‌توانید تاریخ و زمان فعلی را در قالبی نزدیک‌تر به آنچه می‌خواهید نمایش دهید چاپ کنید. یک کاربر:

projects/datetime/main.go

...

func main() {
	currentTime := time.Now()
	fmt.Println("The time is", currentTime)
	
	fmt.Printf("%d-%d-%d %d:%d:%d\n",
		currentTime.Year(),
		currentTime.Month(),
		currentTime.Day(),
		currentTime.Hour(),
		currentTime.Hour(),
		currentTime.Second())
}

هنگامی که به روز رسانی های خود را در فایل main.go ذخیره کردید، آن را با استفاده از دستور go run مانند قبل اجرا کنید:

go run main.go

خروجی شبیه به این خواهد بود:

 

Output

The time is 2021-08-15 14:30:45.0000001 -0500 CDT m=+0.000066626
2021-8-15 14:14:45

این بار ممکن است خروجی شما به چیزی که می‌خواهید نزدیک‌تر باشد، اما هنوز چند چیز وجود دارد که می‌توان در مورد خروجی اصلاح کرد. ماه اکنون دوباره در قالب عددی نمایش داده می‌شود، زیرا قالب fmt.Printf از %d برای نشان دادن زمان استفاده می‌کند. نوع ماه باید از یک عدد استفاده کند نه رشته، اما فقط به صورت تک رقمی نشان داده می‌شود. اگر می‌خواهید دو رقم نمایش داده شود، می‌توانید فرمت fmt.Printf را برای گفتن آن تغییر دهید، اما اگر بخواهید به جای زمان ۲۴ ساعته همانطور که در خروجی بالا نشان داده شده است، یک زمان ۱۲ ساعته را نیز نشان دهید، چطور؟ با استفاده از روش fmt.Printf، شما باید برای محاسبه آن، ریاضی خود را انجام دهید. چاپ تاریخ و زمان با استفاده از fmt.Printf امکان پذیر است، اما همانطور که می بینید، در نهایت می تواند دست و پا گیر شود. با انجام این کار، می‌توانید برای هر قسمتی که می‌خواهید نمایش دهید تعداد زیادی خط داشته باشید، یا باید تعدادی از محاسبات خود را برای تعیین اینکه چه چیزی را نمایش دهید انجام دهید.

در این قسمت برنامه جدیدی برای دریافت زمان فعلی با استفاده از time.Now ایجاد کردید. هنگامی که زمان فعلی را داشتید، سپس از عملکردهای مختلفی مانند سال و ساعت در زمان. نوع زمان برای چاپ اطلاعات مربوط به زمان فعلی استفاده کردید. با این حال، نمایش آن در یک قالب سفارشی شروع به کار زیادی کرد. برای آسان‌تر کردن این نوع کار رایج، بسیاری از زبان‌های برنامه‌نویسی، از جمله Go، روش خاصی را برای قالب‌بندی تاریخ‌ها و زمان‌ها ارائه می‌کنند، مشابه روشی که fmt.Printf می‌تواند برای قالب‌بندی یک رشته استفاده شود.

چاپ و قالب بندی تاریخ های خاص

علاوه بر سال، ساعت و سایر روش‌های مرتبط با داده که نوع time.Time ارائه می‌کند، روشی به نام Format را نیز ارائه می‌کند. متد Format به شما امکان می‌دهد یک رشته طرح‌بندی، شبیه به فرمت fmt.Printf یا fmt.Sprintf ارائه دهید، که به روش Format می‌گوید که چگونه می‌خواهید تاریخ و زمان چاپ شود. در این بخش، خروجی زمانی را که در بخش گذشته اضافه کرده‌اید، تکرار می‌کنید، اما به روشی بسیار مختصرتر با استفاده از روش Format.

با این حال، قبل از استفاده از روش Format، اگر هر بار که برنامه را اجرا می‌کنید تغییری نمی‌کند، بهتر است ببینید که چگونه Format بر خروجی یک تاریخ و زمان تأثیر می‌گذارد. تا به حال، شما زمان فعلی را با استفاده از زمان دریافت می‌کردید. اکنون، بنابراین هر بار که آن را اجرا می‌کردید، عدد متفاوتی نشان داده می‌شد. بسته Go time یک تابع مفید دیگر را ارائه می دهد، تابع time.Date، که به شما امکان می دهد تاریخ و زمان خاصی را برای نمایش زمان تعیین کنید.

برای شروع استفاده از time.Date به جای time.Now در برنامه خود، فایل main.go را دوباره باز کنید و آن را به روز کنید تا جایگزین time.Now با time.Date شود:

projects/datetime/main.go

...

func main() {
	theTime := time.Date(2021, 8, 15, 14, 30, 45, 100, time.Local)
	fmt.Println("The time is", theTime)
}

پارامترهای تابع time.Date شامل سال، ماه، روز ماه، ساعت، دقیقه و ثانیه از تاریخ و زمانی است که می‌خواهید زمان. زمان برای آن تعیین کنید. اولین پارامتر از دو پارامتر آخر برای نانوثانیه ها محاسبه می شود و آخرین پارامتر منطقه زمانی برای ایجاد زمان است. استفاده از مناطق زمانی خود بعداً در این آموزش پوشش داده شده است.

پس از ذخیره به روز رسانی ها، برنامه خود را با استفاده از go run اجرا کنید:

go run main.go

خروجی شبیه به این خواهد بود:

 

Output

The time is 2021-08-15 14:30:45.0000001 -0500 CDT

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

سفارشی کردن رشته های تاریخ با استفاده از روش قالب

بسیاری از زبان‌های برنامه‌نویسی دیگر روشی مشابه برای قالب‌بندی تاریخ‌ها و زمان‌ها برای نمایش دارند، اما روشی که Go طرح‌بندی آن فرمت‌ها را می‌سازد ممکن است کمی متفاوت از آنچه شما به آن عادت کرده‌اید، باشد، اگر از آن‌ها در زبان‌های دیگر استفاده کرده باشید. در زبان‌های دیگر، قالب‌بندی تاریخ از سبکی مشابه نحوه عملکرد Printf در Go استفاده می‌کند، با یک کاراکتر % و به دنبال آن یک حرف نشان‌دهنده بخشی از تاریخ یا زمان برای درج. به عنوان مثال، یک سال 4 رقمی ممکن است با %Y نشان داده شود. اما در Go، این بخش‌های تاریخ یا زمان با کاراکترهایی نشان داده می‌شوند که تاریخ خاصی را نشان می‌دهند. برای گنجاندن یک سال 4 رقمی در قالب تاریخ Go، در واقع باید سال 2006 را در خود رشته قرار دهید. مزیت این نوع چیدمان این است که آنچه در کد می بینید در واقع نشان دهنده چیزی است که در خروجی خواهید دید. وقتی بتوانید نمایشی از خروجی خود را مشاهده کنید، بررسی مجدد اینکه قالب شما با آنچه به دنبال آن هستید مطابقت دارد آسان تر می شود و همچنین درک خروجی برنامه را برای سایر توسعه دهندگان بدون اجرای برنامه آسان تر می کند. اول برنامه

تاریخ خاصی که Go برای طرح‌بندی تاریخ و زمان در قالب‌بندی رشته استفاده می‌کند، 01/02 03:04:05 06 -0700 است. اگر به هر جزء تاریخ و زمان نگاه کنید، خواهید دید که برای هر قسمت یک عدد افزایش می یابد. ماه اول در 01 می آید، پس از آن روز ماه در 02، سپس ساعت در 03، دقیقه در 04، دوم در 05، سال در 06 (یا 2006) و، در نهایت، منطقه زمانی در 07. به خاطر سپردن این ترتیب، ایجاد قالب‌های تاریخ و زمان را در آینده آسان‌تر می‌کند. نمونه‌هایی از گزینه‌های موجود برای قالب‌بندی را نیز می‌توانید در اسناد بسته زمانی Go پیدا کنید.

اکنون، از این روش جدید Format برای تکرار و پاکسازی قالب تاریخی که در بخش آخر چاپ کرده اید استفاده کنید. برای نمایش به چندین خط و فراخوانی تابع نیاز داشت و استفاده از روش Format باید کپی کردن آن را بسیار ساده تر و تمیزتر کند.

فایل main.go را باز کنید و یک تماس جدید fmt.Println اضافه کنید و آن را با تاریخ فرمت شده با استفاده از روش Format به Time ارسال کنید:

projects/datetime/main.go

...

func main() {
	theTime := time.Date(2021, 8, 15, 14, 30, 45, 100, time.Local)
	fmt.Println("The time is", theTime)

	fmt.Println(theTime.Format("2006-1-2 15:4:5"))
}

اگر به طرح مورد استفاده برای قالب نگاه کنید، خواهید دید که از همان زمان از بالا برای تعیین نحوه قالب بندی تاریخ و زمان استفاده می کند (2 ژانویه 2006). نکته ای که باید به آن توجه کرد این است که ساعت به جای 03 مانند مثال قبلی از 15 استفاده می کند. این نشان می دهد که شما می خواهید ساعت به جای 12 ساعت در قالب 24 ساعته نمایش داده شود.

برای دیدن خروجی از این فرمت جدید، برنامه خود را ذخیره کرده و با استفاده از go run اجرا کنید:

go run main.go

خروجی شبیه به این خواهد بود:

 

Output

The time is 2021-08-15 14:30:45.0000001 -0500 CDT
2021-8-15 14:30:45

خروجی ای که اکنون می بینید مشابه خروجی انتهای بخش قبلی خواهد بود، اما انجام آن بسیار ساده تر بود. تنها چیزی که نیاز داشتید یک خط کد و یک رشته طرح بندی بود. تابع Format بقیه کارها را برای شما انجام می دهد.

بسته به تاریخ یا زمانی که نمایش می‌دهید، استفاده از قالبی با طول متغیر مانند فرمتی که هنگام چاپ مستقیم اعداد با آن به پایان رسید، ممکن است برای خود، کاربران یا سایر کدهایی که سعی در خواندن مقدار دارند، خواندن آن دشوار باشد. استفاده از 1 برای قالب ماه باعث می شود که مارس به صورت 3 نمایش داده شود، در حالی که اکتبر از دو کاراکتر استفاده می کند و به صورت 10 نشان داده می شود. اکنون main.go را باز کنید و با طرح بندی ساختارمندتر، یک خط اضافی به برنامه خود اضافه کنید. در این چیدمان، یک پیشوند 0 روی کامپوننت ها قرار دهید و ساعت را برای استفاده از قالب 12 ساعته به روز کنید:

projects/datetime/main.go

...

func main() {
	theTime := time.Date(2021, 8, 15, 14, 30, 45, 100, time.Local)
	fmt.Println("The time is", theTime)

	fmt.Println(theTime.Format("2006-1-2 15:4:5"))
	fmt.Println(theTime.Format("2006-01-02 03:04:05 pm"))
}

پس از ذخیره کد خود، دوباره برنامه را با استفاده از go run اجرا کنید:

go run main.go

خروجی شبیه به این خواهد بود:

 

Output

The time is 2021-08-15 14:30:45.0000001 -0500 CDT
2021-8-15 14:30:45
2021-08-15 02:30:45 pm

خواهید دید که با افزودن یک پیشوند 0 به اعداد در رشته طرح بندی، 8 ماه در خروجی جدید به 08 تبدیل می شود تا با چیدمان مطابقت داشته باشد. ساعت که اکنون در قالب 12 ساعته است، پیشوند 0 خود را نیز دارد. با این حال، در پایان، آنچه در خروجی مشاهده می کنید، فرمتی را که در کد می بینید منعکس می کند، بنابراین در صورت نیاز، تغییر قالب آسان تر است.

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

با استفاده از فرمت از پیش تعریف شده

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

یکی از قالب‌های موجود و اغلب مورد استفاده، فرمت تعریف‌شده در RFC 3339 است. RFC سندی است که برای تعریف نحوه عملکرد استانداردها در اینترنت استفاده می‌شود و RFC‌های دیگر می‌توانند بر روی یکدیگر ایجاد کنند. یک RFC وجود دارد که نحوه عملکرد HTTP را تعریف می کند (RFC 2616)، برای مثال، و دیگرانی که در بالای آن برای تعریف بیشتر HTTP ساخته می شوند. بنابراین، در مورد RFC 3339، RFC یک قالب استاندارد برای استفاده برای مهرهای زمانی در اینترنت تعریف می‌کند. این قالب در سراسر اینترنت شناخته شده و به خوبی پشتیبانی می شود، بنابراین شانس دیدن آن در جای دیگر زیاد است.

هر یک از قالب‌های زمانی از پیش تعریف‌شده در بسته زمانی با یک رشته const به نام قالبی که نشان می‌دهند نشان داده می‌شوند. فرمت RFC 3339 دو فرمت در دسترس دارد، یکی به نام time.RFC3339 و دیگری به نام time.RFC3339Nano. تفاوت فرمت ها در این است که نسخه time.RFC3339Nano شامل نانوثانیه در فرمت است.

اکنون فایل main.go خود را دوباره باز کنید و برنامه خود را به روز کنید تا از فرمت time.RFC3339Nano برای خروجی آن استفاده کنید:

projects/datetime/main.go

...

func main() {
	theTime := time.Date(2021, 8, 15, 14, 30, 45, 100, time.Local)
	fmt.Println("The time is", theTime)
	
	fmt.Println(theTime.Format(time.RFC3339Nano))
}

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

برای دیدن خروجی، برنامه خود را با go run دوباره اجرا کنید:

go run main.go

خروجی شبیه به این خواهد بود:

 

Output

The time is 2021-08-15 14:30:45.0000001 -0500 CDT
2021-08-15T14:30:45.0000001-05:00

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

در این بخش، برنامه خود را به روز کردید تا از روش Format برای چاپ تاریخ و زمان استفاده کنید. استفاده از این طرح‌بندی انعطاف‌پذیر به کد شما اجازه می‌دهد شبیه به خروجی نهایی باشد. در نهایت، شما از یکی از رشته های چیدمان از پیش تعریف شده برای چاپ تاریخ و زمان با استفاده از قالبی که به خوبی پشتیبانی می شود استفاده کردید. در بخش بعدی، برنامه خود را به‌روزرسانی می‌کنید تا همان مقدار رشته را به یک مقدار time.Time تبدیل کنید که می‌توانید با آن کار کنید.

تجزیه تاریخ و زمان در رشته ها

اغلب هنگام توسعه برنامه‌ها، با تاریخ‌هایی مواجه می‌شوید که به‌عنوان مقادیر رشته‌ای نشان داده می‌شوند که باید به نحوی آن‌ها را تفسیر کنید. گاهی اوقات، شما باید قسمت تاریخ مقدار را بدانید، گاهی اوقات ممکن است نیاز به دانستن بخش زمانی داشته باشید، و برخی دیگر ممکن است به کل مقدار نیاز داشته باشید. بسته Go time علاوه بر استفاده از روش Format برای ایجاد مقادیر رشته ای از مقادیر time.Time، تابع time.Parse را برای تبدیل یک رشته به مقدار time.Time ارائه می دهد. تابع time.Parse شبیه به روش Format عمل می کند، به این صورت که طرح تاریخ و زمان مورد انتظار و همچنین مقدار رشته را به عنوان پارامتر می گیرد.

اکنون فایل main.go را در برنامه خود باز کنید و آن را به روز کنید تا از تابع time.Parse برای تجزیه یک timeString به متغیر time.Time استفاده کنید:

projects/datetime/main.go

...

func main() {
	timeString := "2021-08-15 02:30:45"
	theTime, err := time.Parse("2006-01-02 03:04:05", timeString)
	if err != nil {
		fmt.Println("Could not parse time:", err)
	}
	fmt.Println("The time is", theTime)
	
	fmt.Println(theTime.Format(time.RFC3339Nano))
}

برخلاف روش Format، متد time.Parse همچنین در صورتی که مقدار رشته ارسال شده با طرح ارائه شده به عنوان پارامتر اول مطابقت نداشته باشد، مقدار خطای احتمالی را برمی گرداند. اگر به چیدمان استفاده شده نگاه کنید، می بینید که چیدمان داده شده به time.Parse از همان 1 برای ماه، 2 برای روز ماه و غیره استفاده می کند که در متد Format استفاده می شود.

پس از ذخیره به روز رسانی های خود، می توانید برنامه به روز شده خود را با استفاده از go run اجرا کنید:

go run main.go

خروجی شبیه به این خواهد بود:

 

Output

The time is 2021-08-15 02:30:45 +0000 UTC
2021-08-15T02:30:45Z

در این خروجی باید به چند نکته توجه کرد. یکی این که منطقه زمانی که از timeString تجزیه می‌شود از منطقه زمانی پیش‌فرض استفاده می‌کند که یک افست +0 است و به عنوان زمان جهانی هماهنگ (UTC) شناخته می‌شود. از آنجایی که نه مقدار زمان و نه چیدمان شامل منطقه زمانی نمی شود، تابع time.Parse نمی داند که با کدام منطقه زمانی مرتبط شود. اگر زمانی به آن نیاز داشتید، بسته زمانی شامل یک تابع time.ParseInLocation می‌شود تا بتوانید مکان مورد استفاده را ارائه دهید. بخش دیگری که باید به آن توجه کرد در خروجی RFC 3339 است. خروجی از طرح‌بندی نانو RFC3339 استفاده می‌کند، اما خروجی شامل هیچ نانوثانیه‌ای نمی‌شود. این به این دلیل است که تابع time.Parse هیچ نانوثانیه‌ای را تجزیه نمی‌کند، بنابراین مقدار روی پیش‌فرض 0 تنظیم می‌شود. وقتی نانوثانیه‌ها 0 هستند، فرمت time.RFC3339Nano شامل نانوثانیه‌ها در خروجی نمی‌شود.

متد time.Parse همچنین می‌تواند از هر یک از طرح‌بندی‌های زمانی از پیش تعریف‌شده ارائه شده در بسته زمان هنگام تجزیه یک مقدار رشته استفاده کند. برای مشاهده این موضوع در عمل، فایل main.go خود را باز کنید و مقدار timeString را به روز کنید تا با خروجی time.RFC3339Nano قبل از آن مطابقت داشته باشد و پارامتر time.Parse را برای مطابقت به روز کنید:

projects/datetime/main.go

...

func main() {
	timeString := "2021-08-15T14:30:45.0000001-05:00"
	theTime, err := time.Parse(time.RFC3339Nano, timeString)
	if err != nil {
		fmt.Println("Could not parse time:", err)
	}
	fmt.Println("The time is", theTime)
	
	fmt.Println(theTime.Format(time.RFC3339Nano))
}

هنگامی که کد را به روز کردید، می توانید برنامه خود را ذخیره کرده و با استفاده از go run دوباره اجرا کنید:

go run main.go

خروجی شبیه به این خواهد بود:

 

Output

The time is 2021-08-15 14:30:45.0000001 -0500 CDT
2021-08-15T14:30:45.0000001-05:00

این بار، خروجی از روش Format نشان می دهد که time.Parse توانست هم منطقه زمانی و هم نانوثانیه های timeString را تجزیه کند.

در این بخش، از تابع time.Parse برای تجزیه یک مقدار رشته تاریخ و زمان فرمت شده دلخواه و همچنین یک طرح از پیش تعریف شده استفاده کردید. با این حال، تا کنون، با مناطق زمانی مختلفی که دیده‌اید تعاملی نداشته‌اید. مجموعه دیگری از ویژگی‌هایی که Go برای زمان ارائه می‌کند. نوع زمان، امکان تبدیل بین مناطق زمانی مختلف است، همانطور که در بخش بعدی خواهید دید.

کار با مناطق زمانی

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

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

اکنون، فایل main.go خود را باز کنید تا برنامه خود را به روز کنید تا از روش UTC در theTime برای برگرداندن نسخه UTC زمان استفاده کنید:

projects/datetime/main.go

...

func main() {
	theTime := time.Date(2021, 8, 15, 14, 30, 45, 100, time.Local)
	fmt.Println("The time is", theTime)
	fmt.Println(theTime.Format(time.RFC3339Nano))
	
	utcTime := theTime.UTC()
	fmt.Println("The UTC time is", utcTime)
	fmt.Println(utcTime.Format(time.RFC3339Nano))
}

این بار برنامه شما theTime را به‌عنوان زمان. مقدار زمان در منطقه زمانی محلی شما ایجاد می‌کند، آن را در دو قالب مختلف چاپ می‌کند، سپس از روش UTC برای ترجمه آن زمان از زمان محلی شما به زمان UTC استفاده می‌کند.

برای دیدن خروجی برنامه، می توانید آن را با استفاده از go run اجرا کنید:

go run main.go

خروجی شبیه به این خواهد بود:

 

Output

The time is 2021-08-15 14:30:45.0000001 -0500 CDT
2021-08-15T14:30:45.0000001-05:00
The UTC time is 2021-08-15 19:30:45.0000001 +0000 UTC
2021-08-15T19:30:45.0000001Z

خروجی شما بسته به منطقه زمانی محلی شما متفاوت خواهد بود، اما در خروجی بالا، خواهید دید که اولین باری که چاپ می شود در CDT (زمان نوری مرکزی آمریکای شمالی) است که 5- ساعت از UTC فاصله دارد. هنگامی که متد UTC فراخوانی شد و زمان UTC چاپ شد، می توانید ببینید که ساعت در زمان از 14 به 19 می رسد، زیرا تبدیل زمان به UTC پنج ساعت اضافه می کند.

همچنین می‌توان یک زمان UTC را به زمان محلی با استفاده از روش محلی در یک زمان. زمان به همان روش تبدیل کرد. فایل main.go خود را دوباره باز کنید و آن را به روز کنید تا یک تماس به روش محلی در utcTime اضافه کنید تا آن را به منطقه زمانی محلی خود تبدیل کنید:

projects/datetime/main.go

...

func main() {
	theTime := time.Date(2021, 8, 15, 14, 30, 45, 100, time.Local)
	fmt.Println("The time is", theTime)
	fmt.Println(theTime.Format(time.RFC3339Nano))
	
	utcTime := theTime.UTC()
	fmt.Println("The UTC time is", utcTime)
	fmt.Println(utcTime.Format(time.RFC3339Nano))

	localTime := utcTime.Local()
	fmt.Println("The Local time is", localTime)
	fmt.Println(localTime.Format(time.RFC3339Nano))
}

هنگامی که فایل شما ذخیره شد، برنامه خود را با استفاده از go run اجرا کنید:

go run main.go

خروجی شبیه به این خواهد بود:

 

Output

The time is 2021-08-15 14:30:45.0000001 -0500 CDT
2021-08-15T14:30:45.0000001-05:00
The UTC time is 2021-08-15 19:30:45.0000001 +0000 UTC
2021-08-15T19:30:45.0000001Z
The Local time is 2021-08-15 14:30:45.0000001 -0500 CDT
2021-08-15T14:30:45.0000001-05:00

خواهید دید که زمان UTC دوباره به منطقه زمانی محلی شما تبدیل شده است. در خروجی بالا، تبدیل UTC به CDT به این معنی است که پنج ساعت از UTC کم شده است و ساعت را از 19 به 14 تغییر می دهد.

در این بخش، شما برنامه خود را برای تبدیل تاریخ و زمان بین منطقه زمانی محلی خود و منطقه زمانی استاندارد UTC با استفاده از روش UTC به روز کردید، سپس دوباره با استفاده از روش محلی برگشتید.

هنگامی که مقادیر تاریخ و زمان خود را در دسترس قرار دادید، تعدادی ویژگی اضافی وجود دارد که بسته Go time ارائه می دهد که می تواند در برنامه های شما مفید باشد. یکی از این ویژگی ها تعیین این است که آیا زمان معین قبل یا بعد از دیگری است.

مقایسه دو بار

مقایسه دو تاریخ با یکدیگر، به دلیل همه متغیرهایی که باید در هنگام مقایسه آنها در نظر گرفته شوند، گاهی اوقات به طرز فریبنده ای دشوار است. به عنوان مثال، نیاز به در نظر گرفتن مناطق زمانی، یا این واقعیت که ماه ها تعداد روزهای متفاوتی از یکدیگر دارند. بسته زمان چند روش را برای آسان تر کردن این کار ارائه می دهد.

بسته زمان دو روش برای آسان‌تر کردن این مقایسه‌ها ارائه می‌کند: روش‌های قبل و بعد، که در نوع time.Time در دسترس هستند. این روش‌ها هر دو یک مقدار زمانی واحد را می‌پذیرند و بسته به اینکه زمانی که فراخوانی می‌شوند قبل یا بعد از زمان ارائه شده باشد، true یا false را برمی‌گردانند.

برای مشاهده نمونه ای از این توابع در عمل، فایل main.go خود را باز کنید و آن را به روز کنید تا شامل دو تاریخ مختلف باشد، سپس از قبل و بعد برای مقایسه آن تاریخ ها برای دیدن خروجی استفاده کنید:

projects/datetime/main.go

...

func main() {
	firstTime := time.Date(2021, 8, 15, 14, 30, 45, 100, time.UTC)
	fmt.Println("The first time is", firstTime)

	secondTime := time.Date(2021, 12, 25, 16, 40, 55, 200, time.UTC)
	fmt.Println("The second time is", secondTime)

	fmt.Println("First time before second?", firstTime.Before(secondTime))
	fmt.Println("First time after second?", firstTime.After(secondTime))

	fmt.Println("Second time before first?", secondTime.Before(firstTime))
	fmt.Println("Second time after first?", secondTime.After(firstTime))
}

هنگامی که فایل خود را به روز کردید، آن را ذخیره کرده و با استفاده از go run اجرا کنید:

go run main.go

خروجی شبیه به این خواهد بود:

 

Output

The first time is 2021-08-15 14:30:45.0000001 +0000 UTC
The second time is 2021-12-25 16:40:55.0000002 +0000 UTC
First time before second? true
First time after second? false
Second time before first? false
Second time after first? true

از آنجایی که کد از تاریخ های صریح در منطقه زمانی UTC استفاده می کند، خروجی شما باید با خروجی بالا مطابقت داشته باشد. خواهید دید که هنگام استفاده از روش Before در firstTime و ارائه آن secondTime برای مقایسه، این درست است که 2021-08-15 قبل از 2021-12-25 است. هنگام استفاده از روش After از firstTime و ارائه secondTime، اشتباه است که 2021-08-15 بعد از 2021-12-25 باشد. تغییر ترتیب فراخوانی متدها در secondTime، همانطور که انتظار می رود، نتایج مخالف را نشان می دهد.

روش دیگر برای مقایسه دو تاریخ و زمان با بسته زمانی، روش Sub است. متد Sub یک تاریخ را از تاریخ دیگر کم می کند و با استفاده از نوع جدیدی به نام time.Duration مقداری را برمی گرداند. بر خلاف یک مقدار time.Time، که یک نقطه مطلق در زمان را نشان می دهد، یک مقدار time.Duration نشان دهنده تفاوت در زمان است. به عنوان مثال، “در یک ساعت” مدت زمان خواهد بود زیرا به معنای چیزی متفاوت بر اساس زمان فعلی روز است، اما “در ظهر” یک زمان خاص و مطلق را نشان می دهد. Go از زمان استفاده می‌کند. نوع مدت زمان در تعدادی مکان، مانند زمانی که می‌خواهید مشخص کنید که یک تابع چه مدت باید قبل از بازگشت خطا منتظر بماند یا در اینجا، جایی که باید بدانید بین یک زمان و زمان دیگر چقدر زمان وجود دارد، استفاده می‌کند.

اکنون فایل main.go خود را به روز کنید تا از روش Sub در مقادیر firstTime و secondTime استفاده کنید و نتایج را چاپ کنید:

projects/datetime/main.go

...

func main() {
	firstTime := time.Date(2021, 8, 15, 14, 30, 45, 100, time.UTC)
	fmt.Println("The first time is", firstTime)

	secondTime := time.Date(2021, 12, 25, 16, 40, 55, 200, time.UTC)
	fmt.Println("The second time is", secondTime)

	fmt.Println("Duration between first and second time is", firstTime.Sub(secondTime))
	fmt.Println("Duration between second and first time is", secondTime.Sub(firstTime))

فایل خود را ذخیره کنید و سپس با استفاده از go run اجرا کنید:

go run main.go

خروجی شبیه به این خواهد بود:

 

Output

The first time is 2021-08-15 14:30:45.0000001 +0000 UTC
The second time is 2021-12-25 16:40:55.0000002 +0000 UTC
Duration between first and second time is -3170h10m10.0000001s
Duration between second and first time is 3170h10m10.0000001s

خروجی بالا می گوید 3170 ساعت، 10 دقیقه، 10 ثانیه و 100 نانوثانیه بین این دو تاریخ وجود دارد و چند نکته در مورد خروجی وجود دارد. اولین مورد این است که مدت زمان بین بار اول و دوم یک مقدار منفی است. این می‌گوید که زمان دوم بعد از زمان اول است و شبیه به زمانی خواهد بود که 5 را از 0 کم کنید و 5- را دریافت کنید. دومین موردی که باید به آن توجه کرد این است که بزرگترین واحد اندازه گیری مدت زمان یک ساعت است، بنابراین آن را به روز یا ماه تقسیم نمی کند. از آنجایی که تعداد روزهای یک ماه یکسان نیست و یک “روز” می تواند در طول سوئیچ برای ساعت تابستانی معنای متفاوتی داشته باشد، یک ساعت دقیق ترین اندازه گیری است که نوسان ندارد.

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

اضافه یا تفریق زمان

هنگام نوشتن یک برنامه، یک عملیات رایج با استفاده از تاریخ و زمان، تعیین زمان گذشته یا آینده بر اساس زمان دیگر است. می‌توان از آن برای عملکرد استفاده کرد، مانند تعیین زمان تمدید اشتراک بعدی، یا اینکه مدت زمان مشخصی از بررسی مقداری گذشته است. در هر صورت، بسته Go time راهی برای مدیریت آن ارائه می دهد. برای پیدا کردن تاریخ دیگری بر اساس تاریخی که قبلاً می‌دانید، باید بتوانید زمان خود را تعیین کنید. مقادیر مدت زمان.

ایجاد یک مقدار time.Duration شبیه نحوه نوشتن مدت زمان روی کاغذ است، فقط با ضرب واحد زمان. به عنوان مثال، برای ایجاد زمان. مدت زمان برای نشان دادن یک ساعت، باید آن را با استفاده از مقدار time.Hour ضرب در تعداد ساعت‌هایی که می‌خواهید زمان را نشان دهید، تعریف کنید.

oneHour := 1 * time.Hour
twoHours := 2 * time.Hour
tenHours := 10 * time.Hour

اعلان واحدهای زمانی کوچکتر به روشی مشابه انجام می شود، به جز استفاده از time.minute، time.second و غیره:

tenMinutes := 10 * time.Minute
fiveSeconds := 5 * time.Second

همچنین می توان یک مدت زمان را به مدت زمان دیگر اضافه کرد تا مجموع مدت زمان ها بدست آید. برای اینکه این را در عمل ببینید، فایل main.go خود را باز کنید و آن را به روز کنید تا یک متغیر toAdd duration را اعلام کنید و مدت زمان های مختلف را به آن اضافه کنید:

projects/datetime/main.go

...

func main() {
	toAdd := 1 * time.Hour
	fmt.Println("1:", toAdd)

	toAdd += 1 * time.Minute
	fmt.Println("2:", toAdd)

	toAdd += 1 * time.Second
	fmt.Println("3:", toAdd)
}

پس از اتمام به روز رسانی، فایل را ذخیره کنید و برنامه خود را با استفاده از go run اجرا کنید:

go run main.go

خروجی شبیه به این خواهد بود:

 

Output

1: 1h0m0s
2: 1h1m0s
3: 1h1m1s

هنگامی که به خروجی نگاه می کنید، خواهید دید که اولین مدت چاپ یک ساعت است که مطابق با زمان 1 * ساعت در کد شما است. در مرحله بعد، 1 * time.Minute را به مقدار toAdd اضافه کردید، که به عنوان مقدار یک ساعت، یک دقیقه نشان داده می شود. در نهایت، 1 * time.Second را به toAdd اضافه کردید، که منجر به مقدار زمان. مدت زمان یک ساعت، یک دقیقه و یک ثانیه شد.

همچنین می توان با اضافه کردن مدت زمان ها در یک عبارت، یا کم کردن مدت زمان از دیگری را ترکیب کرد:

oneHourOneMinute := 1 * time.Hour + 1 * time.Minute
tenMinutes := 1 * time.Hour - 50 * time.Minute

بعد، فایل main.go خود را باز کنید و برنامه خود را به روز کنید تا از ترکیبی مانند این برای کم کردن یک دقیقه و یک ثانیه از toAdd استفاده کنید:

projects/datetime/main.go

...

func main() {
	
	...
	
	toAdd += 1 * time.Second
	fmt.Println("3:", toAdd)
	
	toAdd -= 1*time.Minute + 1*time.Second
	fmt.Println("4:", toAdd)
}

پس از ذخیره کد خود، می توانید برنامه را با استفاده از go run اجرا کنید:

go run main.go

خروجی شبیه به این خواهد بود:

 

Output

1: 1h0m0s
2: 1h1m0s
3: 1h1m1s
4: 1h0m0s

خط چهارم جدید اضافه شده به خروجی کد جدیدی را که برای تفریق مجموع 1 * time.Minute و 1 * time اضافه کرده اید نشان می دهد.

استفاده از این مدت زمان‌ها که با متد Add of the time.Time جفت شده‌اند، به شما این امکان را می‌دهد که یک مقدار زمانی را که قبلاً دارید انتخاب کنید و زمان را در نقطه دلخواه دیگری قبل یا بعد از آن زمان تعیین کنید. برای مشاهده نمونه ای از این در حال اجرا، فایل main.go خود را باز کنید و آن را به روز کنید تا مقدار toAdd را روی 24 ساعت یا 24 * time.Hour تنظیم کنید. سپس، از روش افزودن روی مقدار time.Time استفاده کنید تا ببینید 24 ساعت پس از آن نقطه چه زمانی خواهد بود:

projects/datetime/main.go

...

func main() {
	theTime := time.Date(2021, 8, 15, 14, 30, 45, 100, time.UTC)
	fmt.Println("The time is", theTime)

	toAdd := 24 * time.Hour
	fmt.Println("Adding", toAdd)

	newTime := theTime.Add(toAdd)
	fmt.Println("The new time is", newTime)
}

پس از ذخیره فایل خود، برنامه خود را با استفاده از go run اجرا کنید:

go run main.go

خروجی شبیه به این خواهد بود:

 

Output

The time is 2021-08-15 14:30:45.0000001 +0000 UTC
Adding 24h0m0s
The new time is 2021-08-16 14:30:45.0000001 +0000 UTC

با نگاهی به خروجی، خواهید دید که افزودن 24 ساعت به 2021-08-15 منجر به تاریخ جدید 2021-08-16 می شود.

برای کم کردن زمان، از روش افزودن نیز استفاده می‌کنید که کمی غیرمعمول است. از آنجایی که از روش Sub برای بدست آوردن اختلاف زمان بین دو تاریخ استفاده می شود، با استفاده از Add با مقدار منفی، زمان را از مقدار time.Time کم می کنید.

یک بار دیگر، برای مشاهده این مورد در برنامه خود، فایل main.go خود را باز کرده و آن را به روز کنید تا مقدار 24 ساعته toAdd را به مقدار منفی تغییر دهید:

projects/datetime/main.go

...

func main() {
	theTime := time.Date(2021, 8, 15, 14, 30, 45, 100, time.UTC)
	fmt.Println("The time is", theTime)

	toAdd := -24 * time.Hour
	fmt.Println("Adding", toAdd)

	newTime := theTime.Add(toAdd)
	fmt.Println("The new time is", newTime)
}

پس از ذخیره فایل خود، یک بار دیگر برنامه خود را با استفاده از go run اجرا کنید:

go run main.go

خروجی شبیه به این خواهد بود:

 

Output

The time is 2021-08-15 14:30:45.0000001 +0000 UTC
Adding -24h0m0s
The new time is 2021-08-14 14:30:45.0000001 +0000 UTC

این بار در خروجی خواهید دید که به جای اضافه کردن 24 ساعت به زمان اصلی، تاریخ جدید 24 ساعت قبل از زمان اصلی است.

در این بخش از time.Hour، time.Minute و time.Second برای ایجاد مقادیر time.Duration در درجات مختلف استفاده کردید. شما همچنین از مقادیر time.Duration با متد Add استفاده کردید تا یک مقدار time.Time جدید قبل و بعد از مقدار اصلی بدست آورید. با ترکیب زمان. اکنون، روش افزودن، و روش های قبل یا بعد، به عملکرد قدرتمند تاریخ و زمان برای برنامه های خود دسترسی خواهید داشت.

نتیجه

در این آموزش، شما از time.Now برای بازیابی یک مقدار time.Time برای زمان محلی فعلی در رایانه خود استفاده کردید، سپس از سال، ماه، ساعت و روش های دیگر برای دسترسی به اطلاعات خاصی در مورد آن زمان استفاده کردید. سپس، از روش Format برای چاپ زمان با استفاده از یک قالب سفارشی و یک قالب از پیش تعریف شده استفاده کردید. در مرحله بعد، از تابع time.Parse برای تفسیر مقدار رشته با زمان در آن و استخراج مقدار زمان از آن استفاده کردید. هنگامی که مقدار زمان را داشتید، از روش های UTC و Local برای ترجمه زمان بین UTC و منطقه زمانی محلی خود استفاده کردید. پس از آن، قبل از استفاده از روش افزودن برای یافتن زمان نسبت به مقدار زمانی متفاوت، از روش Sub برای بدست آوردن مدت زمان بین دو زمان مختلف استفاده کردید.

استفاده از توابع و روش‌های مختلفی که در این آموزش توضیح داده شده است، کمک زیادی به برنامه‌های شما می‌کند، اما بسته Go time در صورت علاقه، تعدادی ویژگی دیگر را نیز شامل می‌شود.

https://vpsgol.net/product/vps-germany/

 

https://vpsgol.net/product/vps-usa/

 

https://vpsgol.net/product/vps-france/

 

https://vpsgol.net/product/vps-canada/

 

https://vpsgol.net/product/vps-poland/

 

https://vpsgol.net/product/vps-netherlands/

 

https://vpsgol.net/product/vps-england/

برچسب‌ها:VPS یا سرور مجازیآموزش برنامه GOاتصال به سرور مجازی ویندوزبرنامه Goخرید سرور مجازیراه اندازی اولیه سرورسرور مجازیسفارشی کردن رشته های تاریخ

  • behnam gol mohamadi
  • ۰
  • ۰

نحوه راه اندازی یک سرور پخش ویدئو با استفاده از Nginx-RTMP در اوبونتو 20.04

ورود به سایت

معرفی

موارد استفاده زیادی برای پخش ویدیو وجود دارد. ارائه دهندگان خدمات مانند Twitch برای مدیریت جنبه های اکتشاف وب و مدیریت جامعه جریان بسیار محبوب هستند و نرم افزار رایگان مانند OBS Studio به طور گسترده برای ترکیب همپوشانی های ویدئویی از چندین منبع جریان مختلف در زمان واقعی استفاده می شود. در حالی که این پلتفرم ها بسیار قدرتمند هستند، در برخی موارد ممکن است بخواهید بتوانید جریانی را میزبانی کنید که به سایر ارائه دهندگان خدمات متکی نیست.

در این آموزش، نحوه پیکربندی وب سرور Nginx را برای میزبانی یک جریان ویدیوی RTMP مستقل که می‌تواند در برنامه‌های مختلف لینک و مشاهده شود، پیکربندی کنید. RTMP، پروتکل پیام‌رسانی بلادرنگ، اصول اکثر جریان‌های ویدئویی اینترنتی را تعریف می‌کند. همچنین یاد خواهید گرفت که چگونه جریان های HLS و DASH را میزبانی کنید که از پلتفرم های مدرن تری با استفاده از همین فناوری پشتیبانی می کنند.

پیش نیازها

برای تکمیل این راهنما، شما نیاز دارید:

  • یک سرور اوبونتو 20.04 و یک کاربر غیر ریشه با امتیازات sudo.
  • Nginx نصب شده است، به دنبال نحوه نصب Nginx در اوبونتو 20.04.

این آموزش از نام دامنه نگهدارنده your_domain برای URL ها و نام هاست استفاده می کند. در حین کار با آموزش، نام دامنه یا آدرس IP خود را جایگزین کنید.

مرحله 1 – نصب و پیکربندی Nginx-RTMP

اکثر ابزارهای مدرن جریان از پروتکل RTMP پشتیبانی می کنند، که پارامترهای اساسی یک جریان ویدئوی اینترنتی را تعریف می کند. وب سرور Nginx شامل ماژولی است که به شما امکان می دهد یک جریان RTMP با حداقل پیکربندی از یک URL اختصاصی ارائه دهید، درست مانند دسترسی HTTP به صفحات وب به طور پیش فرض. ماژول Nginx RTMP به طور خودکار در Nginx گنجانده نشده است، اما در Ubuntu 20.04 و اکثر توزیع‌های لینوکس دیگر می‌توانید آن را به عنوان یک بسته اضافی نصب کنید.

با اجرای دستورات زیر به عنوان یک کاربر غیر ریشه برای به روز رسانی لیست بسته های خود و نصب ماژول Nginx شروع کنید:

sudo apt update
sudo apt install libnginx-mod-rtmp

نصب ماژول به طور خودکار شروع به ارائه یک جریان نمی کند. شما باید یک بلوک پیکربندی را به فایل پیکربندی Nginx خود اضافه کنید که مکان و نحوه در دسترس بودن جریان را مشخص کند.

با استفاده از nano یا ویرایشگر متن مورد علاقه خود، فایل پیکربندی اصلی Nginx، /etc/nginx/nginx.conf را باز کنید و این بلوک پیکربندی را به انتهای فایل اضافه کنید:

sudo nano /etc/nginx/nginx.conf

/etc/nginx/nginx.conf

. . .
rtmp {
        server {
                listen 1935;
                chunk_size 4096;
                allow publish 127.0.0.1;
                deny publish all;

                application live {
                        live on;
                        record off;
                }
        }
}
  • listen 1935 به این معنی است که RTMP برای اتصالات در پورت 1935 که استاندارد است گوش می دهد.
  • chunk_size 4096 به این معنی است که RTMP داده ها را در بلوک های 4 کیلوبایتی ارسال می کند که این نیز استاندارد است.
  • اجازه انتشار 127.0.0.1 و انکار انتشار همه به این معنی است که سرور فقط اجازه می دهد ویدیو از همان سرور منتشر شود تا دیگر کاربران جریان های خود را تحت فشار قرار ندهند.
  • application live یک بلوک برنامه را تعریف می کند که در مسیر /live URL در دسترس خواهد بود.
  • live on حالت زنده را فعال می‌کند تا چندین کاربر بتوانند به طور همزمان به جریان شما متصل شوند، یک فرض اولیه پخش ویدیو.
  • ضبط کردن عملکرد ضبط Nginx-RTMP را غیرفعال می کند، به طوری که تمام جریان ها به طور پیش فرض به طور جداگانه در دیسک ذخیره نمی شوند.

ذخیره کنید و فایل را ببندید. اگر از nano استفاده می کنید، Ctrl+X را فشار دهید، سپس وقتی از شما خواسته شد، Y و Enter را فشار دهید.

این شروع پیکربندی RTMP شما را فراهم می کند. به طور پیش فرض، به پورت 1935 گوش می دهد، به این معنی که باید آن پورت را در فایروال خود باز کنید. اگر ufw را به عنوان بخشی از تنظیمات اولیه سرور خود پیکربندی کرده اید، دستور زیر را اجرا کنید.

sudo ufw allow 1935/tcp

اکنون می توانید Nginx را با تغییرات خود بارگیری مجدد کنید:

sudo systemctl reload nginx.service

اکنون باید یک سرور RTMP در حال کار داشته باشید. در بخش بعدی، پخش ویدیو را از منابع محلی و راه دور به سرور RTMP شما پوشش خواهیم داد.

مرحله 2 – ارسال ویدیو به سرور RTMP شما

راه های مختلفی برای ارسال ویدیو به سرور RTMP وجود دارد. یکی از گزینه‌ها استفاده از ffmpeg، یک ابزار محبوب صوتی و تصویری خط فرمان، برای پخش مستقیم یک فایل ویدیویی بر روی سرور است. اگر قبلاً یک فایل ویدیویی روی سرور ندارید، می‌توانید با استفاده از youtube-dl، یک ابزار خط فرمان برای ضبط ویدیو از پلتفرم‌های پخش جریانی مانند YouTube، آن را دانلود کنید. برای استفاده از youtube-dl، به نصب پایتون به روز روی سرور خود نیز نیاز دارید.

ابتدا پایتون و مدیریت بسته آن یعنی pip را نصب کنید:

sudo apt install python3-pip

در مرحله بعد، از pip برای نصب youtube-dl استفاده کنید:

pip install youtube-dl

اکنون می توانید از youtube-dl برای دانلود یک ویدیو از یوتیوب استفاده کنید. اگر موردی را در ذهن ندارید، این ویدیو را با معرفی پلتفرم اپلیکیشن DigitalOcean امتحان کنید:

youtube-dl https://www.youtube.com/watch?v=iom_nhYQIYk

زمانی که youtube-dl جریان‌های ویدیویی و صوتی را که بارگیری می‌کند در یک فایل واحد ترکیب می‌کند، مقداری خروجی را مشاهده خواهید کرد – این طبیعی است.

 

Output

[youtube] iom_nhYQIYk: Downloading webpage
WARNING: Requested formats are incompatible for merge and will be merged into mkv.
[download] Destination: Introducing App Platform by DigitalOcean-iom_nhYQIYk.f137.mp4
[download] 100% of 32.82MiB in 08:40
[download] Destination: Introducing App Platform by DigitalOcean-iom_nhYQIYk.f251.webm
[download] 100% of 1.94MiB in 00:38
[ffmpeg] Merging formats into "Introducing App Platform by DigitalOcean-iom_nhYQIYk.mkv"
Deleting original file Introducing App Platform by DigitalOcean-iom_nhYQIYk.f137.mp4 (pass -k to keep)
Deleting original file Introducing App Platform by DigitalOcean-iom_nhYQIYk.f251.webm (pass -k to keep)

اکنون باید یک فایل ویدیویی در فهرست فعلی خود با عنوانی مانند معرفی پلتفرم برنامه توسط DigitalOcean-iom_nhYQIYk.mkv داشته باشید. برای استریم کردن آن، باید ffmpeg را نصب کنید:

sudo apt install ffmpeg

و از ffmpeg برای ارسال آن به سرور RTMP خود استفاده کنید:

ffmpeg -re -i “Introducing App Platform by DigitalOcean-iom_nhYQIYk.mkv” -c:v copy -c:a aac -ar 44100 -ac 1 -f flv rtmp://localhost/live/stream

این دستور ffmpeg چند کار را انجام می دهد تا ویدیو را برای یک قالب مناسب پخش آماده کند. این یک آموزش ffmpeg نیست، بنابراین نیازی به بررسی دقیق آن ندارید، اما می توانید گزینه های مختلف را به صورت زیر درک کنید:

  • -re مشخص می کند که ورودی با نرخ فریم اصلی خود خوانده می شود.
  • -i “Introducing App Platform by DigitalOcean-iom_nhYQIYk.mkv” مسیر فایل ورودی ما را مشخص می کند.
  • -c:v روی کپی تنظیم شده است، به این معنی که شما در حال کپی کردن فرمت ویدیویی هستید که از YouTube به صورت بومی دریافت کرده اید.
  • -c:a پارامترهای دیگری دارد، یعنی aac -ar 44100 -ac 1، زیرا باید صدا را به یک فرمت مناسب RTMP نمونه برداری کنید. aac یک کدک صوتی با پشتیبانی گسترده است، 44100 هرتز یک فرکانس رایج است، و -ac 1 اولین نسخه از مشخصات AAC را برای اهداف سازگاری مشخص می کند.
  • -f flv برای حداکثر سازگاری با RTMP، ویدیو را در یک ظرف با فرمت flv می پیچد.

این ویدیو به rtmp://localhost/live/stream ارسال می‌شود، زیرا شما بلوک پیکربندی زنده را در مرحله 1 تعریف کرده‌اید، و پخش یک URL دلخواه برای این ویدیو است.

در حالی که ffmpeg در حال پخش ویدیو است، کدهای زمانی را چاپ می کند:

 

Output

frame=  127 fps= 25 q=-1.0 size=     405kB time=00:00:05.00 bitrate= 662.2kbits/s speed=frame=  140 fps= 25 q=-1.0 size=     628kB time=00:00:05.52 bitrate= 931.0kbits/s speed=frame=  153 fps= 25 q=-1.0 size=     866kB time=00:00:06.04 bitrate=1173.1kbits/s speed=

این خروجی استاندارد ffmpeg است. اگر ویدیو را به فرمت دیگری تبدیل می‌کردید، اینها ممکن است برای درک میزان کارآمدی نمونه‌گیری مجدد ویدیو مفید باشند، اما در این مورد، فقط می‌خواهید ببینید که به طور مداوم پخش می‌شود. با استفاده از این ویدئوی نمونه، باید fps دقیق = 25 افزایش دریافت کنید.

در حالی که ffmpeg در حال اجرا است، می توانید از پخش کننده ویدیو به جریان RTMP خود متصل شوید. اگر VLC، mpv، یا پخش کننده رسانه دیگری را به صورت محلی نصب کرده اید، باید بتوانید جریان خود را با باز کردن URL rtmp://your_domain/live/stream در پخش کننده رسانه خود مشاهده کنید. پس از اتمام پخش ویدیو توسط ffmpeg، پخش جریانی شما پایان می یابد. اگر می‌خواهید به طور نامحدود به چرخش ادامه دهد، می‌توانید -stream_loop -1 را به ابتدای دستور ffmpeg خود اضافه کنید.

اکنون که یاد گرفتید منابع ویدئویی استاتیک را از خط فرمان استریم کنید، نحوه پخش ویدئو از منابع پویا را با استفاده از OBS روی دسکتاپ یاد خواهید گرفت.

مرحله 3 – پخش ویدیو به سرور خود از طریق OBS (اختیاری)

پخش جریانی از طریق ffmpeg زمانی راحت است که یک ویدیو آماده دارید که می‌خواهید پخش کنید، اما پخش زنده می‌تواند بسیار پویاتر باشد. محبوب ترین نرم افزار برای پخش زنده OBS یا Open Broadcaster Software است – این نرم افزار رایگان، منبع باز و بسیار قدرتمند است.

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

پس از نصب OBS، پیکربندی آن به معنای شخصی‌سازی پنجره‌های دسکتاپ و منابع صوتی است که می‌خواهید به جریان خود اضافه کنید، و سپس اعتبارنامه‌ها را برای یک سرویس پخش اضافه کنید. این آموزش پیکربندی استریم شما را پوشش نمی‌دهد، زیرا در اولویت قرار دارد، و به طور پیش‌فرض، می‌توانید تنها با پخش جریانی کل دسک‌تاپ خود، یک نسخه نمایشی فعال داشته باشید. برای تنظیم اعتبار سرویس پخش خود، منوی تنظیمات OBS را باز کنید، به گزینه Stream بروید و گزینه های زیر را وارد کنید:

Streaming Service: Custom
Server: rtmp://your_domain/live
Play Path/Stream Key: obs_stream

obs_stream مسیری است که خودسرانه انتخاب شده است – در این مورد، ویدیوی شما در rtmp://your_domain/live/obs_stream در دسترس خواهد بود. شما نیازی به فعال کردن احراز هویت ندارید، اما باید یک ورودی اضافی به لیست سفید IP که در مرحله 1 پیکربندی کرده اید اضافه کنید.

بر روی سرور، فایل پیکربندی اصلی Nginx، /etc/nginx/nginx.conf را باز کنید و یک ورودی اجازه انتشار اضافی برای آدرس IP محلی خود اضافه کنید. اگر آدرس IP محلی خود را نمی دانید، بهتر است فقط به سایتی مانند What’s my IP بروید که می تواند به شما بگوید از کجا به آن دسترسی داشته اید:

sudo nano /etc/nginx/nginx.conf

/etc/nginx/nginx.conf

. . .
                allow publish 127.0.0.1;
                allow publish your_local_ip_address;
                deny publish all;
. . .

فایل را ذخیره کرده و ببندید، سپس Nginx را دوباره بارگیری کنید:

sudo systemctl reload nginx.service

اکنون باید بتوانید منوی تنظیمات OBS را ببندید و روی Start Streaming از رابط اصلی کلیک کنید! سعی کنید جریان خود را مانند قبل در پخش کننده رسانه مشاهده کنید. اکنون که اصول پخش ویدئو را در عمل مشاهده کرده اید، می توانید چند ویژگی دیگر را به سرور خود اضافه کنید تا آن را برای تولید آماده تر کنید.

مرحله 4 – افزودن مانیتورینگ به پیکربندی (اختیاری)

اکنون که Nginx را برای پخش جریانی ویدیو با استفاده از ماژول Nginx-RTMP پیکربندی کرده اید، گام بعدی رایج این است که صفحه آمار RTMP را فعال کنید. به جای افزودن جزئیات بیشتر و بیشتر پیکربندی به فایل اصلی nginx.conf، Nginx به شما امکان می دهد پیکربندی های هر سایت را به فایل های جداگانه در یک زیر شاخه به نام sites-available/ اضافه کنید. در این مورد، یکی به نام rtmp ایجاد خواهید کرد:

sudo nano /etc/nginx/sites-available/rtmp

مطالب زیر را اضافه کنید:

/etc/nginx/sites-available/rtmp

server {
    listen 8080;
    server_name  localhost;

    # rtmp stat
    location /stat {
        rtmp_stat all;
        rtmp_stat_stylesheet stat.xsl;
    }
    location /stat.xsl {
        root /var/www/html/rtmp;
    }

    # rtmp control
    location /control {
        rtmp_control all;
    }
}

ذخیره کنید و فایل را ببندید. فایل stat.xsl از این بلوک پیکربندی برای استایل دادن و نمایش یک صفحه آمار RTMP در مرورگر شما استفاده می شود. توسط کتابخانه libnginx-mod-rtmp که قبلا نصب کرده اید ارائه می شود، اما به طور پیش فرض فشرده می شود، بنابراین باید آن را از حالت فشرده خارج کنید و در پوشه /var/www/html/rtmp قرار دهید تا با پیکربندی بالا مطابقت داشته باشد. . توجه داشته باشید که می توانید اطلاعات اضافی درباره هر یک از این گزینه ها را در اسناد Nginx-RTMP بیابید.

پوشه /var/www/html/rtmp را ایجاد کنید و سپس فایل stat.xsl.gz را با دستورات زیر از حالت فشرده خارج کنید:

sudo mkdir /var/www/html/rtmp
sudo gunzip -c /usr/share/doc/libnginx-mod-rtmp/examples/stat.xsl.gz > /var/www/html/rtmp/stat.xsl`

در نهایت، برای دسترسی به صفحه آماری که اضافه کردید، باید پورت دیگری را در فایروال خود باز کنید. به طور خاص، دستورالعمل listen با پورت 8080 پیکربندی شده است، بنابراین باید یک قانون برای دسترسی به Nginx در آن پورت اضافه کنید. با این حال، احتمالاً نمی‌خواهید دیگران بتوانند به صفحه آمار شما دسترسی داشته باشند، بنابراین بهتر است فقط به آدرس IP خود اجازه دهید. دستور زیر را اجرا کنید:

sudo ufw allow from your_ip_address to any port http-alt

در مرحله بعد، باید این پیکربندی جدید را فعال کنید. قرارداد Nginx ایجاد پیوندهای نمادین (مانند میانبرها) از فایل‌های موجود در سایت‌های موجود/به پوشه دیگری به نام sites-enabled/هنگامی که تصمیم به فعال یا غیرفعال کردن آن‌ها دارید، است. با استفاده از مسیرهای کامل برای وضوح، این پیوند را ایجاد کنید:

sudo ln -s /etc/nginx/sites-available/rtmp /etc/nginx/sites-enabled/rtmp

اکنون می توانید دوباره Nginx را برای پردازش تغییرات خود بارگیری مجدد کنید:

sudo systemctl reload nginx.service

اکنون باید بتوانید در مرورگر به http://your_domain:8080/stat بروید تا صفحه آمار RTMP را ببینید. در حین پخش ویدیو از صفحه بازدید کرده و آن را بازخوانی کنید و مشاهده کنید که آمار جریان تغییر می کند.

اکنون مشاهده کرده اید که چگونه می توانید جریان ویدیوی خود را نظارت کنید و آن را به ارائه دهندگان شخص ثالث ارسال کنید. در بخش آخر، یاد خواهید گرفت که چگونه آن را مستقیماً در یک مرورگر بدون استفاده از پلتفرم‌های پخش جریانی شخص ثالث یا برنامه‌های پخش کننده رسانه مستقل ارائه کنید.

مرحله 5 – ایجاد جریان های مدرن برای مرورگرها (اختیاری)

به عنوان آخرین مرحله، ممکن است بخواهید از پروتکل های جریان جدیدتر پشتیبانی اضافه کنید تا کاربران بتوانند مستقیماً با استفاده از یک مرورگر وب، ویدیو را از سرور شما پخش کنند. دو پروتکل وجود دارد که می توانید برای ایجاد جریان های ویدئویی مبتنی بر HTTP از آنها استفاده کنید: HLS اپل و MPEG DASH. هر دو مزایا و معایبی دارند، بنابراین احتمالاً می خواهید از هر دو پشتیبانی کنید.

ماژول Nginx-RTMP از هر دو استاندارد پشتیبانی می کند. برای افزودن پشتیبانی HLS و DASH به سرور خود، باید بلوک rtmp را در فایل nginx.conf خود تغییر دهید. /etc/nginx/nginx.conf را با استفاده از nano یا ویرایشگر دلخواه خود باز کنید، سپس دستورالعمل های هایلایت شده زیر را اضافه کنید:

sudo nano /etc/nginx/nginx.conf

/etc/nginx/nginx.conf

. . .
rtmp {
        server {
. . .
                application live {
                        live on;
                        record off;
                        hls on;
                        hls_path /var/www/html/stream/hls;
                        hls_fragment 3;
                        hls_playlist_length 60;

                        dash on;
                        dash_path /var/www/html/stream/dash;
                }
        }
}
. . .

ذخیره کنید و فایل را ببندید. بعد، این را به پایین سایت های خود اضافه کنید-available/rtmp:

sudo nano /etc/nginx/sites-available/rtmp

/etc/nginx/sites-available/rtmp

. . .
server {
    listen 8088;

    location / {
        add_header Access-Control-Allow-Origin *;
        root /var/www/html/stream;
    }
}

types {
    application/dash+xml mpd;
}

ذخیره کنید و فایل را ببندید. توجه داشته باشید که در اینجا از پورت 8088 استفاده کنید، که یکی دیگر از انتخاب‌های دلخواه برای این آموزش برای جلوگیری از تضاد با سرویس‌هایی است که ممکن است در پورت 80 یا 443 اجرا شود.

sudo ufw allow 8088/tcp

در نهایت، یک دایرکتوری جریان در ریشه وب خود ایجاد کنید تا با بلوک پیکربندی مطابقت داشته باشد تا Nginx بتواند فایل های لازم برای HLS و DASH را ایجاد کند:

sudo mkdir /var/www/html/stream

بارگیری مجدد Nginx:

sudo systemctl reload nginx

اکنون باید یک جریان HLS در http://your_domain:8088/hls/stream.m3u8 و یک جریان DASH در http://your_domain:8088/dash/stream.mpd موجود باشد. این نقاط پایانی هر ابرداده لازم را در بالای فید ویدیوی RTMP شما به منظور پشتیبانی از APIهای مدرن تولید می کنند.

نتیجه

گزینه های پیکربندی که در این آموزش استفاده کردید همگی در صفحه ویکی Nginx RTMP مستند شده اند. ماژول‌های Nginx معمولاً نحو مشترکی را به اشتراک می‌گذارند و مجموعه بسیار وسیعی از گزینه‌های پیکربندی را در معرض دید قرار می‌دهند، و شما می‌توانید اسناد آنها را برای تغییر هر یک از تنظیمات خود از اینجا مرور کنید.

تقریباً تمام پخش ویدیوی اینترنتی در بالای RTMP، HLS و DASH پیاده‌سازی می‌شود و با استفاده از رویکردی که در این آموزش بررسی کرده‌اید، می‌توانید جریان خود را از طریق سایر سرویس‌های پخش ارائه کنید یا به هر طریق دیگری که می‌خواهید آن را در معرض دید قرار دهید. در مرحله بعد، می توانید به پیکربندی Nginx به عنوان یک پروکسی معکوس توجه کنید تا برخی از این نقاط پایانی مختلف ویدیو را به عنوان زیر دامنه در دسترس قرار دهید.

 

 

https://vpsgol.net/product/vps-germany/

 

https://vpsgol.net/product/vps-usa/

 

https://vpsgol.net/product/vps-france/

 

https://vpsgol.net/product/vps-canada/

 

https://vpsgol.net/product/vps-poland/

 

https://vpsgol.net/product/vps-netherlands/

 

https://vpsgol.net/product/vps-england/

 

برچسب‌ها:Nginx-RTMPVPS یا سرور مجازیاتصال به سرور مجازی لینوکسانواع سرور مجازیخرید سرور مجازیراه اندازی سرورراه اندازی یک سرور پخش ویدئوسرور RTMPسرور مجازی آمریکانصب و پیکربندی Nginx-RTMPوب سرور Nginx

  • behnam gol mohamadi
  • ۰
  • ۰

نحوه انجام جستجوی تمام متن در MongoDB

ورود به سایت

معرفی

پرس‌و‌جوهای MongoDB که داده‌ها را با جستجوی تطابق دقیق، استفاده از مقایسه‌های بیشتر یا کمتر یا با استفاده از عبارات منظم فیلتر می‌کنند، در بسیاری از موقعیت‌ها به اندازه کافی خوب کار می‌کنند. با این حال، وقتی صحبت از فیلتر کردن فیلدهای حاوی داده های متنی غنی می شود، این روش ها کوتاهی می کنند.

تصور کنید “دستور پخت قهوه” را در یک موتور جستجوی وب تایپ کرده اید، اما فقط صفحاتی را که حاوی همان عبارت هستند، باز می گرداند. در این مورد، ممکن است دقیقاً چیزی را که به دنبال آن بودید پیدا نکنید، زیرا اکثر وب سایت های محبوب با دستور پخت قهوه ممکن است عبارت دقیق «دستور پخت قهوه» را نداشته باشند. اگر بخواهید این عبارت را در یک موتور جستجوی واقعی وارد کنید، ممکن است صفحاتی با عناوینی مانند «نوشیدنی های قهوه عالی (با دستور پخت!)» یا «نوشیدنی ها و خوراکی های کافی شاپ که می توانید در خانه درست کنید» پیدا کنید. در این مثال‌ها، کلمه «قهوه» وجود دارد، اما عناوین حاوی شکل دیگری از کلمه «رسپی» هستند یا آن را به طور کامل حذف می‌کنند.

این سطح از انعطاف در تطبیق متن با یک عبارت جستجو برای موتورهای جستجوی متن کامل که در جستجوی داده های متنی تخصص دارند، معمول است. چندین ابزار منبع باز تخصصی برای چنین برنامه هایی در حال استفاده وجود دارد که ElasticSearch یک انتخاب بسیار محبوب است. با این حال، برای سناریوهایی که به ویژگی های جستجوی قوی موجود در موتورهای جستجوی اختصاصی نیاز ندارند، برخی از سیستم های مدیریت پایگاه داده همه منظوره قابلیت های جستجوی متن کامل خود را ارائه می دهند.

در این آموزش، شما به عنوان مثال یاد خواهید گرفت که چگونه یک نمایه متن در MongoDB ایجاد کنید و از آن برای جستجوی اسناد در پایگاه داده در برابر پرس و جوها و فیلترهای جستجوی متن کامل استفاده کنید.

پیش نیازها

برای دنبال کردن این آموزش، شما نیاز دارید:

  • سروری با کاربر معمولی و غیر روت با امتیازات sudo و فایروال پیکربندی شده با UFW. این آموزش با استفاده از سروری که اوبونتو 20.04 را اجرا می کند تأیید شده است، و شما می توانید با دنبال کردن این آموزش اولیه راه اندازی سرور برای اوبونتو 20.04 سرور خود را آماده کنید.
  • MongoDB روی سرور شما نصب شده است.
  • نمونه MongoDB سرور شما با فعال کردن احراز هویت و ایجاد یک کاربر مدیریتی ایمن می شود
  • آشنایی با پرس و جو مجموعه های MongoDB و فیلتر کردن نتایج.

مرحله 1 – آماده سازی داده های تست

برای کمک به یادگیری نحوه انجام جستجوی متن کامل در MongoDB، این مرحله نحوه باز کردن پوسته MongoDB برای اتصال به نمونه MongoDB نصب شده محلی خود را شرح می دهد. همچنین نحوه ایجاد یک مجموعه نمونه و درج چند سند نمونه در آن را توضیح می دهد. این نمونه داده در دستورات و مثال‌هایی در سراسر این راهنما استفاده می‌شود تا به توضیح نحوه استفاده از MongoDB برای جستجوی داده‌های متنی کمک کند.

برای ایجاد این مجموعه نمونه، به عنوان کاربر مدیریتی خود به پوسته MongoDB متصل شوید. این آموزش از قراردادهای آموزش امنیتی MongoDB پیش نیاز پیروی می کند و فرض می کند که نام این کاربر مدیریتی AdminSammy و پایگاه داده احراز هویت آن admin است. مطمئن شوید که این جزئیات را در دستور زیر تغییر دهید تا تنظیمات خود را نشان دهد، اگر متفاوت است:

mongo -u AdminSammy -p –authenticationDatabase admin

رمز عبوری را که در حین نصب تنظیم کرده اید وارد کنید تا به پوسته دسترسی پیدا کنید. پس از ارائه رمز عبور، درخواست شما به علامت بزرگتر از تغییر خواهد کرد:

>

برای درک اینکه چگونه جستجوی متن کامل را می توان برای اسناد در MongoDB اعمال کرد، به مجموعه ای از اسناد نیاز دارید که بتوانید آنها را فیلتر کنید. این راهنما از مجموعه ای از اسناد نمونه استفاده می کند که شامل نام و توضیحات چندین نوع مختلف نوشیدنی قهوه است. این اسناد همان فرمت سند نمونه زیر را دارند که نوشیدنی قهوه کوبایی را توصیف می کند:

Example Cafecito document

{
    "name": "Cafecito",
    "description": "A sweet and rich Cuban hot coffee made by topping an espresso shot with a thick sugar cream foam."
}

این سند شامل دو فیلد است: نام نوشیدنی قهوه و توضیحات طولانی تر که اطلاعات پس زمینه ای در مورد نوشیدنی و مواد تشکیل دهنده آن ارائه می دهد.

متد insertMany() زیر را در پوسته MongoDB اجرا کنید تا مجموعه‌ای به نام recipes ایجاد کنید و در همان زمان، پنج سند نمونه را در آن قرار دهید:

db.recipes.insertMany([
{“name”: “Cafecito”, “description”: “A sweet and rich Cuban hot coffee made by topping an espresso shot with a thick sugar cream foam.”},
{“name”: “New Orleans Coffee”, “description”: “Cafe Noir from New Orleans is a spiced, nutty coffee made with chicory.”},
{“name”: “Affogato”, “description”: “An Italian sweet dessert coffee made with fresh-brewed espresso and vanilla ice cream.”},
{“name”: “Maple Latte”, “description”: “A wintertime classic made with espresso and steamed milk and sweetened with some maple syrup.”},
{“name”: “Pumpkin Spice Latte”, “description”: “It wouldn’t be autumn without pumpkin spice lattes made with espresso, steamed milk, cinnamon spices, and pumpkin puree.”}
])

 

این متد لیستی از شناسه‌های شی اختصاص داده شده به اشیاء تازه درج شده را برمی‌گرداند:

 

Output

{
        "acknowledged" : true,
        "insertedIds" : [
            ObjectId("61895d2787f246b334ece911"),
            ObjectId("61895d2787f246b334ece912"),
            ObjectId("61895d2787f246b334ece913"),
            ObjectId("61895d2787f246b334ece914"),
            ObjectId("61895d2787f246b334ece915")
        ]
}

می توانید با اجرای متد find() در مجموعه دستور العمل ها بدون آرگومان بررسی کنید که اسناد به درستی درج شده اند. با این کار تمام اسناد موجود در مجموعه بازیابی می شود:

db.recipes.find()

 

Output

{ "_id" : ObjectId("61895d2787f246b334ece911"), "name" : "Cafecito", "description" : "A sweet and rich Cuban hot coffee made by topping an espresso shot with a thick sugar cream foam." }
. . .

با داده های نمونه در محل، آماده شروع یادگیری نحوه استفاده از ویژگی های جستجوی متن کامل MongoDB هستید.

مرحله 2 – ایجاد یک فهرست متن

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

با این حال، نمایه متنی، نوع خاصی از نمایه است که برای تسهیل بیشتر جستجوی فیلدهای حاوی داده های متنی استفاده می شود. هنگامی که کاربر یک فهرست متنی ایجاد می کند، MongoDB به طور خودکار هر کلمه توقف خاص زبان را از جستجو حذف می کند. این بدان معنی است که MongoDB رایج ترین کلمات برای زبان داده شده (در انگلیسی، کلماتی مانند “a”، “an”، “the” یا “this”) را نادیده می گیرد.

MongoDB همچنین نوعی پسوند stemming را در جستجوها پیاده سازی خواهد کرد. این شامل شناسایی قسمت ریشه عبارت جستجو شده توسط MongoDB و استفاده از سایر اشکال دستور زبان آن ریشه (که با افزودن پسوندهای رایج مانند “-ing”، “-ed” یا شاید “-er” ایجاد شده است) را به عنوان معادل ریشه برای کلمه جستجو می کند.

به لطف این ویژگی‌ها و سایر ویژگی‌ها، MongoDB می‌تواند با انعطاف‌پذیری بیشتری از پرسش‌های نوشته شده به زبان طبیعی پشتیبانی کند و نتایج بهتری ارائه دهد.

شما فقط می توانید یک فهرست متنی برای هر مجموعه MongoDB ایجاد کنید، اما این فهرست را می توان با استفاده از بیش از یک فیلد ایجاد کرد. در مجموعه مثال ما، متن مفیدی در هر دو قسمت نام و توضیحات هر سند ذخیره شده است. ایجاد یک فهرست متنی برای هر دو فیلد می تواند مفید باشد.

متد ()createIndex زیر را اجرا کنید که یک فهرست متنی برای دو فیلد ایجاد می کند:

db.recipes.createIndex({ “name”: “text”, “description”: “text” });

برای هر یک از دو فیلد، نام و توضیحات، نوع فهرست روی متن تنظیم می‌شود و به MongoDB می‌گوید یک فهرست متنی متناسب با جستجوی متن کامل بر اساس این فیلدها ایجاد کند. خروجی ایجاد ایندکس را تایید می کند:

 

Output

{
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 1,
        "numIndexesAfter" : 2,
        "ok" : 1
}

اکنون که نمایه را ایجاد کرده اید، می توانید از آن برای ارسال عبارت های جستجوی متن کامل در پایگاه داده استفاده کنید. در مرحله بعد، یاد خواهید گرفت که چگونه کوئری هایی را که شامل تک کلمه و چند کلمه هستند اجرا کنید.

مرحله 3 – جستجو برای یک یا چند کلمه جداگانه

شاید رایج ترین مشکل جستجو جستجوی اسنادی باشد که حاوی یک یا چند کلمه جداگانه هستند.

به طور معمول، کاربران انتظار دارند که موتور جستجو در تعیین محل نمایش عبارات جستجوی معین انعطاف پذیر باشد. به عنوان مثال، اگر بخواهید از هر موتور جستجوی وب محبوبی استفاده کنید و عبارت «قهوه شیرین تند» را تایپ کنید، احتمالاً انتظار نتایجی را ندارید که حاوی این سه کلمه به همان ترتیب باشد. احتمال بیشتری وجود دارد که انتظار داشته باشید لیستی از صفحات وب حاوی کلمات “قهوه”، “شیرین” و “ادویه” باشد اما لزوماً بلافاصله در نزدیکی یکدیگر نیستند.

همچنین این روشی است که MongoDB هنگام استفاده از نمایه های متنی به پرس و جوهای جستجوی معمولی نزدیک می شود. در این مرحله توضیح داده می شود که MongoDB چگونه پرس و جوهای جستجو را با چند مثال تفسیر می کند.

برای شروع، بگویید که می‌خواهید نوشیدنی‌های قهوه را با ادویه در دستور غذا جستجو کنید، بنابراین با استفاده از دستور زیر کلمه spiced را به تنهایی جستجو کنید:

db.recipes.find({ $text: { $search: “spiced” } });

توجه داشته باشید که نحو هنگام استفاده از جستجوی تمام متن کمی با پرس و جوهای معمولی متفاوت است. نام فیلدهای فردی – مانند نام یا توضیحات – در سند فیلتر ظاهر نمی شوند. در عوض، کوئری از عملگر $text استفاده می‌کند و به MongoDB می‌گوید که این کوئری قصد دارد از فهرست متنی که قبلا ایجاد کرده‌اید استفاده کند. لازم نیست بیشتر از آن مشخص باشید، زیرا همانطور که به یاد دارید، یک مجموعه ممکن است فقط یک فهرست متنی داشته باشد. در داخل سند جاسازی شده برای این فیلتر، اپراتور $search است که عبارت جستجو را به عنوان مقدار آن در نظر گرفته است. در این مثال، پرس و جو یک کلمه است: spiced.

پس از اجرای این دستور، MongoDB لیستی از اسناد زیر را تولید می کند:

 

Output

{ "_id" : ObjectId("61895d2787f246b334ece915"), "name" : "Pumpkin Spice Latte", "description" : "It wouldn't be autumn without pumpkin spice lattes made with espresso, steamed milk, cinnamon spices, and pumpkin puree." }
{ "_id" : ObjectId("61895d2787f246b334ece912"), "name" : "New Orleans Coffee", "description" : "Cafe Noir from New Orleans is a spiced, nutty coffee made with chicory." }

دو سند در مجموعه نتایج وجود دارد که هر دو حاوی کلماتی شبیه عبارت جستجو هستند. در حالی که سند قهوه نیواورلئان دارای کلمه تند در توضیحات است، سند Pumpkin Spice Late چنین نیست.

صرف نظر از این، به لطف استفاده MongoDB از stemming، همچنان با این کوئری بازگردانده شد. MongoDB کلمه spiced را به صرف ادویه حذف کرد، ادویه را در فهرست جستجو کرد و همچنین آن را ریشه‌یابی کرد. به همین دلیل، کلمات ادویه و ادویه در سند Pumpkin Spice Late با عبارت جستجو با موفقیت مطابقت داشت، حتی اگر هیچ یک از آن کلمات را به طور خاص جستجو نکردید.

حالا، فرض کنید به نوشیدنی های اسپرسو علاقه خاصی دارید. سعی کنید اسناد را با یک پرس و جوی دو کلمه ای، اسپرسوی تند، جستجو کنید تا به دنبال قهوه ای تند و مبتنی بر اسپرسو بگردید.

db.recipes.find({ $text: { $search: “spiced espresso” } });

لیست نتایج این بار طولانی تر از قبل است:

 

Output

{ "_id" : ObjectId("61895d2787f246b334ece914"), "name" : "Maple Latte", "description" : "A wintertime classic made with espresso and steamed milk and sweetened with some maple syrup." }
{ "_id" : ObjectId("61895d2787f246b334ece913"), "name" : "Affogato", "description" : "An Italian sweet dessert coffee made with fresh-brewed espresso and vanilla ice cream." }
{ "_id" : ObjectId("61895d2787f246b334ece911"), "name" : "Cafecito", "description" : "A sweet and rich Cuban hot coffee made by topping an espresso shot with a thick sugar cream foam." }
{ "_id" : ObjectId("61895d2787f246b334ece915"), "name" : "Pumpkin Spice Latte", "description" : "It wouldn't be autumn without pumpkin spice lattes made with espresso, steamed milk, cinnamon spices, and pumpkin puree." }
{ "_id" : ObjectId("61895d2787f246b334ece912"), "name" : "New Orleans Coffee", "description" : "Cafe Noir from New Orleans is a spiced, nutty coffee made with chicory." }

هنگام استفاده از چندین کلمه در یک عبارت جستجو، MongoDB یک عملیات OR منطقی را انجام می دهد، بنابراین یک سند فقط باید با یک قسمت از عبارت مطابقت داشته باشد تا در مجموعه نتایج گنجانده شود. نتایج حاوی اسنادی است که هم دارای ادویه و هم اسپرسو یا هر یک از آنها به تنهایی است. توجه داشته باشید که تا زمانی که کلمات در جایی در سند ظاهر می شوند، لزوماً نیازی نیست که در نزدیکی یکدیگر ظاهر شوند.

در این مرحله، یاد گرفتید که چگونه از یک یا چند کلمه به عنوان جستجوی متنی استفاده کنید، چگونه MongoDB چندین کلمه را با یک عملیات OR منطقی به هم متصل می کند، و چگونه MongoDB stemming را انجام می دهد. در مرحله بعد، از یک عبارت کامل در یک عبارت جستجوی متنی استفاده می‌کنید و شروع به استفاده از استثناها برای محدود کردن بیشتر نتایج جستجو می‌کنید.

مرحله 4 – جستجوی عبارات کامل و استفاده از موارد استثنا

جستجوی کلمات جداگانه ممکن است نتایج بسیار زیادی را به همراه داشته باشد، یا ممکن است نتایج به اندازه کافی دقیق نباشد. در این مرحله، از جستجوی عبارت و حذف برای کنترل دقیق‌تر نتایج جستجو استفاده می‌کنید.

فرض کنید شیرینی دارید، بیرون گرم است، و قهوه ای که روی آن بستنی ریخته شده است، به نظر یک خوراکی خوب است. سعی کنید یک قهوه بستنی را با استفاده از عبارت جستجوی اولیه همانطور که قبلا ذکر شد پیدا کنید:

db.recipes.find({ $text: { $search: “ice cream” } });

پایگاه داده دو دستور پخت قهوه را برمی گرداند:

 

Output

{ "_id" : ObjectId("61895d2787f246b334ece913"), "name" : "Affogato", "description" : "An Italian sweet dessert coffee made with fresh-brewed espresso and vanilla ice cream." }
{ "_id" : ObjectId("61895d2787f246b334ece911"), "name" : "Cafecito", "description" : "A sweet and rich Cuban hot coffee made by topping an espresso shot with a thick sugar cream foam." }

در حالی که سند Affogato با انتظارات شما مطابقت دارد، Cafecito با بستنی درست نمی شود. موتور جستجو با استفاده از عملیات منطقی OR، نتیجه دوم را فقط به این دلیل پذیرفت که کلمه کرم در توضیحات آمده است.

برای اینکه به MongoDB بگویید که به دنبال بستنی به عنوان یک عبارت کامل هستید و نه دو کلمه جداگانه، از عبارت زیر استفاده کنید:

db.recipes.find({ $text: { $search: “\”ice cream\”” } });

به علامت‌های معکوس قبل از هر یک از نقل‌قول‌های دوگانه اطراف عبارت: \”ice cream\” توجه کنید. عبارت جستجویی که اجرا می‌کنید «ice cream» است، با دو نقل قول نشان‌دهنده عبارتی است که باید دقیقاً مطابقت داشته باشد. اسلش‌های معکوس (\) از گیومه‌های دوتایی فرار می‌کنند، بنابراین به عنوان بخشی از نحو JSON در نظر گرفته نمی‌شوند، زیرا می‌توانند در مقدار عملگر $search ظاهر شوند.

این بار، MongoDB یک نتیجه را برمی گرداند:

 

Output

{ "_id" : ObjectId("61895d2787f246b334ece913"), "name" : "Affogato", "description" : "An Italian sweet dessert coffee made with fresh-brewed espresso and vanilla ice cream." }

این سند دقیقاً با عبارت جستجو مطابقت دارد و نه خامه و نه یخ به تنهایی برای به حساب آوردن یک مسابقه کافی نیست.

یکی دیگر از ویژگی های مفید جستجوی متن کامل، اصلاح کننده حذف است. برای نشان دادن نحوه عملکرد، ابتدا پرس و جو زیر را اجرا کنید تا لیستی از تمام نوشیدنی های قهوه موجود در مجموعه بر اساس اسپرسو دریافت کنید:

db.recipes.find({ $text: { $search: “espresso” } });

این پرس و جو چهار سند را برمی گرداند:

 

Output

{ "_id" : ObjectId("61895d2787f246b334ece914"), "name" : "Maple Latte", "description" : "A wintertime classic made with espresso and steamed milk and sweetened with some maple syrup." }
{ "_id" : ObjectId("61895d2787f246b334ece913"), "name" : "Affogato", "description" : "An Italian sweet dessert coffee made with fresh-brewed espresso and vanilla ice cream." }
{ "_id" : ObjectId("61895d2787f246b334ece915"), "name" : "Pumpkin Spice Latte", "description" : "It wouldn't be autumn without pumpkin spice lattes made with espresso, steamed milk, cinnamon spices, and pumpkin puree." }
{ "_id" : ObjectId("61895d2787f246b334ece911"), "name" : "Cafecito", "description" : "A sweet and rich Cuban hot coffee made by topping an espresso shot with a thick sugar cream foam." }

توجه داشته باشید که دو تا از این نوشیدنی ها با شیر سرو می شوند، اما فرض کنید شما یک نوشیدنی بدون شیر می خواهید. این موردی است که در آن محرومیت ها می توانند مفید باشند. در یک جستار، می‌توانید کلماتی را که می‌خواهید در نتایج نشان داده شوند، با کلماتی که می‌خواهید حذف شوند، با اضافه کردن کلمه یا عبارتی که می‌خواهید حذف کنید با علامت منفی (-) بپیوندید.

به عنوان مثال، فرض کنید برای جستجوی قهوه‌های اسپرسو که حاوی شیر نیستند، عبارت زیر را اجرا می‌کنید:

db.recipes.find({ $text: { $search: “espresso -milk” } });

با این پرس و جو، دو سند از نتایج برگشت داده شده قبلی حذف می شوند:

 

Output

{ "_id" : ObjectId("61895d2787f246b334ece913"), "name" : "Affogato", "description" : "An Italian sweet dessert coffee made with fresh-brewed espresso and vanilla ice cream." }
{ "_id" : ObjectId("61895d2787f246b334ece911"), "name" : "Cafecito", "description" : "A sweet and rich Cuban hot coffee made by topping an espresso shot with a thick sugar cream foam." }

شما همچنین می توانید عبارات کامل را حذف کنید. برای جستجوی قهوه های بدون بستنی، می توانید -“ice cream” را در عبارت جستجوی خود قرار دهید. باز هم، باید از نقل قول های دوگانه با اسلش های معکوس فرار کنید، مانند این:

db.recipes.find({ $text: { $search: “espresso -\”ice cream\”” } });

 

Output

{ "_id" : ObjectId("61d48c31a285f8250c8dd5e6"), "name" : "Maple Latte", "description" : "A wintertime classic made with espresso and steamed milk and sweetened with some maple syrup." }
{ "_id" : ObjectId("61d48c31a285f8250c8dd5e7"), "name" : "Pumpkin Spice Latte", "description" : "It wouldn't be autumn without pumpkin spice lattes made with espresso, steamed milk, cinnamon spices, and pumpkin puree." }
{ "_id" : ObjectId("61d48c31a285f8250c8dd5e3"), "name" : "Cafecito", "description" : "A sweet and rich Cuban hot coffee made by topping an espresso shot with a thick sugar cream foam." }

اکنون که یاد گرفتید چگونه اسناد را بر اساس عبارتی متشکل از چند کلمه فیلتر کنید و چگونه کلمات و عبارات خاصی را از نتایج جستجو حذف کنید، می توانید خود را با امتیاز جستجوی تمام متن MongoDB آشنا کنید.

مرحله 5 – امتیاز دادن به نتایج و مرتب سازی بر اساس امتیاز

هنگامی که یک پرس و جو، به ویژه یک پرسش پیچیده، نتایج متعددی را برمی گرداند، برخی از اسناد احتمالاً تطبیق بهتری نسبت به سایرین دارند. به عنوان مثال، وقتی به دنبال نوشیدنی‌های اسپرسو ادویه‌دار می‌گردید، آن‌هایی که هم ادویه‌دار هستند و هم بر پایه اسپرسو، مناسب‌تر از نوشیدنی‌های بدون ادویه هستند یا از اسپرسو به عنوان پایه استفاده نمی‌کنند.

موتورهای جستجوی متن کامل معمولاً یک امتیاز مربوط به نتایج جستجو را تعیین می‌کنند که نشان می‌دهد تا چه حد با عبارت جستجو مطابقت دارند. MongoDB نیز این کار را انجام می دهد، اما ارتباط جستجو به طور پیش فرض قابل مشاهده نیست.

یک بار دیگر اسپرسوی تند را جستجو کنید، اما این بار MongoDB امتیاز مربوط به جستجوی هر نتیجه را نیز بازگردانید. برای انجام این کار، می توانید پس از سند فیلتر پرس و جو یک طرح اضافه کنید:

db.recipes.find(
{ $text: { $search: “spiced espresso” } },
{ score: { $meta: “textScore” } }
)

طرح ریزی { score: {$meta: “textScore” } } از عملگر $meta استفاده می کند، نوع خاصی از طرح ریزی که ابرداده خاصی را از اسناد برگشتی برمی گرداند. این مثال ابرداده textScore اسناد را برمی‌گرداند، یکی از ویژگی‌های داخلی موتور جستجوی متن کامل MongoDB که حاوی امتیاز مربوط به جستجو است.

پس از اجرای پرس و جو، اسناد برگشتی شامل یک فیلد جدید به نام score می شود، همانطور که در سند فیلتر مشخص شده است:

 

Output

{ "_id" : ObjectId("61895d2787f246b334ece913"), "name" : "Affogato", "description" : "An Italian sweet dessert coffee made with fresh-brewed espresso and vanilla ice cream.", "score" : 0.5454545454545454 }
{ "_id" : ObjectId("61895d2787f246b334ece911"), "name" : "Cafecito", "description" : "A sweet and rich Cuban hot coffee made by topping an espresso shot with a thick sugar cream foam.", "score" : 0.5384615384615384 }
{ "_id" : ObjectId("61895d2787f246b334ece914"), "name" : "Maple Latte", "description" : "A wintertime classic made with espresso and steamed milk and sweetened with some maple syrup.", "score" : 0.55 }
{ "_id" : ObjectId("61895d2787f246b334ece912"), "name" : "New Orleans Coffee", "description" : "Cafe Noir from New Orleans is a spiced, nutty coffee made with chicory.", "score" : 0.5454545454545454 }
{ "_id" : ObjectId("61895d2787f246b334ece915"), "name" : "Pumpkin Spice Latte", "description" : "It wouldn't be autumn without pumpkin spice lattes made with espresso, steamed milk, cinnamon spices, and pumpkin puree.", "score" : 2.0705128205128203 }

توجه کنید که امتیاز Pumpkin Spice Latte چقدر بالاتر است، تنها نوشیدنی قهوه که حاوی کلمات spiced و اسپرسو است. با توجه به امتیاز مرتبط MongoDB، مرتبط ترین سند برای آن پرس و جو است. با این حال، به طور پیش فرض، نتایج به ترتیب مرتبط بودن برگردانده نمی شوند.

برای تغییر آن، می توانید یک بند sort() به پرس و جو اضافه کنید، مانند این:

db.recipes.find(
{ $text: { $search: “spiced espresso” } },
{ score: { $meta: “textScore” } }
).sort(
{ score: { $meta: “textScore” } }
);

نحو برای سند مرتب‌سازی مانند پروژکشن است. اکنون لیست اسناد یکسان است، اما ترتیب آنها متفاوت است:

 

Output

{ "_id" : ObjectId("61895d2787f246b334ece915"), "name" : "Pumpkin Spice Latte", "description" : "It wouldn't be autumn without pumpkin spice lattes made with espresso, steamed milk, cinnamon spices, and pumpkin puree.", "score" : 2.0705128205128203 }
{ "_id" : ObjectId("61895d2787f246b334ece914"), "name" : "Maple Latte", "description" : "A wintertime classic made with espresso and steamed milk and sweetened with some maple syrup.", "score" : 0.55 }
{ "_id" : ObjectId("61895d2787f246b334ece913"), "name" : "Affogato", "description" : "An Italian sweet dessert coffee made with fresh-brewed espresso and vanilla ice cream.", "score" : 0.5454545454545454 }
{ "_id" : ObjectId("61895d2787f246b334ece912"), "name" : "New Orleans Coffee", "description" : "Cafe Noir from New Orleans is a spiced, nutty coffee made with chicory.", "score" : 0.5454545454545454 }
{ "_id" : ObjectId("61895d2787f246b334ece911"), "name" : "Cafecito", "description" : "A sweet and rich Cuban hot coffee made by topping an espresso shot with a thick sugar cream foam.", "score" : 0.5384615384615384 }

سند Pumpkin Spice Latte به عنوان اولین نتیجه ظاهر می شود زیرا دارای بالاترین امتیاز مرتبط است.

مرتب سازی نتایج بر اساس امتیاز مربوط به آنها می تواند مفید باشد. این امر به‌ویژه در مورد پرسش‌هایی که حاوی چند کلمه هستند، صادق است، جایی که مناسب‌ترین اسناد معمولاً شامل چندین عبارت جستجو می‌شوند در حالی که اسناد کمتر مرتبط ممکن است فقط شامل یک عبارت باشند.

نتیجه

با دنبال کردن این آموزش، با ویژگی های جستجوی متن کامل MongoDB آشنا شدید. شما یک نمایه متن ایجاد کردید و پرس و جوهای جستجوی متنی را با استفاده از کلمات تک و چندگانه، عبارات کامل و موارد استثنا نوشتید. شما همچنین امتیازات مربوط به اسناد برگشتی را ارزیابی کرده اید و نتایج جستجو را مرتب کرده اید تا ابتدا مرتبط ترین نتایج را نشان دهید. در حالی که ویژگی‌های جستجوی متن کامل MongoDB ممکن است به اندازه ویژگی‌های برخی از موتورهای جستجوی اختصاصی قوی نباشد، اما برای بسیاری از موارد استفاده به اندازه کافی توانایی دارند.

توجه داشته باشید که اصلاح‌کننده‌های جستجوی بیشتری – مانند حساسیت حروف کوچک و بزرگ و پشتیبانی از زبان‌های مختلف – در یک فهرست متنی واحد وجود دارد.

 

https://vpsgol.net/product/vps-germany/

 

https://vpsgol.net/product/vps-usa/

 

https://vpsgol.net/product/vps-france/

 

https://vpsgol.net/product/vps-canada/

 

https://vpsgol.net/product/vps-poland/

 

https://vpsgol.net/product/vps-netherlands/

 

https://vpsgol.net/product/vps-england/

 

  • behnam gol mohamadi
  • ۰
  • ۰

نحوه استفاده از Ansible Vault برای محافظت از داده های حساس Playbook

ورود به سایت

معرفی

Ansible Vault قابلیتی است که به کاربران امکان می دهد مقادیر و ساختارهای داده را در پروژه های Ansible رمزگذاری کنند. این امکان را فراهم می کند تا داده های حساسی را که برای اجرای موفقیت آمیز بازی های Ansible لازم است، اما نباید به صورت عمومی قابل مشاهده باشند، مانند گذرواژه ها یا کلیدهای خصوصی، ایمن کنید. Ansible به طور خودکار محتوای رمزگذاری شده در طاق را در زمان اجرا پس از ارائه کلید رمزگشایی می کند.

در این راهنما، نحوه استفاده از Ansible Vault را نشان خواهیم داد و برخی از روش‌های توصیه شده برای ساده‌سازی استفاده از آن را بررسی خواهیم کرد. ما از سرور اوبونتو 20.04 برای ماشین کنترلی Ansible استفاده خواهیم کرد. به هاست راه دور نیاز نیست.

پیش نیازها

برای پیگیری، به یک سرور اوبونتو 20.04 با یک کاربر غیر ریشه با امتیازات sudo نیاز دارید. شما می توانید راهنمای راه اندازی سرور اولیه Ubuntu 20.04 ما را دنبال کنید تا کاربری با مجوزهای مناسب ایجاد کنید.

در سرور، باید Ansible را نصب و پیکربندی کنید. برای نصب بسته های مناسب می توانید آموزش نصب Ansible در اوبونتو 20.04 را دنبال کنید.

هنگامی که سرور شما با شرایط بالا پیکربندی شده است، این راهنما را ادامه دهید.

Ansible Vault چیست؟

Ansible Vault مکانیزمی است که به محتوای رمزگذاری شده اجازه می دهد تا به طور شفاف در جریان های کاری Ansible گنجانده شود. ابزاری به نام ansible-vault داده‌های محرمانه به نام Secrets را با رمزگذاری روی دیسک ایمن می‌کند. برای ادغام این اسرار با داده‌های معمولی Ansible، هر دو دستور ansible و ansible-playbook، به ترتیب برای اجرای وظایف موقت و playbook ساختاریافته، از رمزگشایی محتوای رمزگذاری‌شده در طاق در زمان اجرا پشتیبانی می‌کنند.

Vault با جزئیات در سطح فایل پیاده سازی می شود، به این معنی که فایل های جداگانه یا رمزگذاری شده یا غیر رمزگذاری شده هستند. از الگوریتم AES256 برای ارائه رمزگذاری متقارن کلید شده به رمز عبور ارائه شده توسط کاربر استفاده می کند. این بدان معنی است که رمز عبور یکسان برای رمزگذاری و رمزگشایی محتوا استفاده می شود، که از نقطه نظر قابلیت استفاده مفید است. Ansible قادر به شناسایی و رمزگشایی هر فایل رمزگذاری شده در طاقچه ای است که در حین اجرای یک کتاب بازی یا کار پیدا می کند.

اکنون که کمی در مورد Vault چیست، می‌توانیم درباره ابزارهایی که Ansible ارائه می‌کند و نحوه استفاده از Vault با گردش‌های کاری موجود بحث کنیم.

تنظیم ویرایشگر Ansible Vault

قبل از استفاده از دستور ansible-vault، ایده خوبی است که ویرایشگر متن مورد نظر خود را مشخص کنید. تعدادی از دستورات Vault شامل باز کردن یک ویرایشگر برای دستکاری محتوای یک فایل رمزگذاری شده است. Ansible به متغیر محیط EDITOR نگاه می کند تا ویرایشگر مورد نظر شما را پیدا کند. اگر این تنظیم نشده باشد، به طور پیش فرض روی vi خواهد بود.

اگر نمی خواهید با ویرایشگر vi ویرایش کنید، باید متغیر EDITOR را در محیط خود تنظیم کنید.

برای تنظیم ویرایشگر برای یک فرمان فردی، دستور را با انتساب متغیر محیطی به صورت زیر اضافه کنید:

EDITOR=nano ansible-vault . . .

برای تداوم این موضوع، فایل ~/.bashrc خود را باز کنید:

nano ~/.bashrc

ویرایشگر مورد نظر خود را با افزودن یک تخصیص EDITOR به انتهای فایل مشخص کنید:

~/.bashrc

export EDITOR=nano

پس از اتمام کار فایل را ذخیره کرده و ببندید.

برای خواندن تغییر در جلسه فعلی، فایل را دوباره منبع کنید:

. ~/.bashrc

برای بررسی اینکه تنظیمات شما اعمال شده است، متغیر EDITOR را نمایش دهید:

echo $EDITOR

 

Output

nano

اکنون که ویرایشگر دلخواه خود را ایجاد کرده اید، می توانیم عملیات های موجود را با دستور ansible-vault مورد بحث قرار دهیم.

نحوه مدیریت فایل های حساس با ansible-vault

دستور ansible-vault رابط اصلی برای مدیریت محتوای رمزگذاری شده در Ansible است. این دستور در ابتدا برای رمزگذاری فایل ها استفاده می شود و سپس برای مشاهده، ویرایش یا رمزگشایی داده ها استفاده می شود.

ایجاد فایل های رمزگذاری شده جدید

برای ایجاد یک فایل جدید رمزگذاری شده با Vault، از دستور ansible-vault create استفاده کنید. نام فایلی را که می خواهید ایجاد کنید ارسال کنید. به عنوان مثال، برای ایجاد یک فایل YAML رمزگذاری شده به نام vault.yml برای ذخیره متغیرهای حساس، می توانید تایپ کنید:

ansible-vault create vault.yml

از شما خواسته می شود رمز عبور را وارد کرده و تأیید کنید:

 

Output

New Vault password: 
Confirm New Vault password:

هنگامی که رمز عبور خود را تأیید کردید، Ansible بلافاصله یک پنجره ویرایش باز می کند که در آن می توانید مطالب مورد نظر خود را وارد کنید.

برای آزمایش عملکرد رمزگذاری، متن آزمایشی را وارد کنید:

vault.yml

Secret information

هنگامی که فایل را ببندید، Ansible محتویات را رمزگذاری می کند. اگر فایل را بررسی کنید، به جای دیدن کلماتی که تایپ کرده اید، یک بلوک رمزگذاری شده خواهید دید:

cat vault.yml

 

Output

$ANSIBLE_VAULT;1.1;AES256
65316332393532313030636134643235316439336133363531303838376235376635373430336333
3963353630373161356638376361646338353763363434360a363138376163666265336433633664
30336233323664306434626363643731626536643833336638356661396364313666366231616261
3764656365313263620a383666383233626665376364323062393462373266663066366536306163
31643731343666353761633563633634326139396230313734333034653238303166

ما می‌توانیم برخی از اطلاعات هدر را ببینیم که Ansible برای اطلاع از نحوه مدیریت فایل استفاده می‌کند و به دنبال آن محتویات رمزگذاری‌شده که به صورت اعداد نمایش داده می‌شوند.

رمزگذاری فایل های موجود

اگر از قبل فایلی دارید که می خواهید با Vault رمزگذاری کنید، به جای آن از دستور encrypt ansible-vault استفاده کنید.

برای آزمایش، می‌توانیم با تایپ کردن یک فایل نمونه ایجاد کنیم:

echo ‘unencrypted stuff’ > encrypt_me.txt

اکنون می توانید فایل موجود را با تایپ کردن رمزگذاری کنید:

ansible-vault encrypt encrypt_me.txt

مجدداً از شما خواسته می شود رمز عبور را ارائه و تأیید کنید. پس از آن، یک پیام رمزگذاری را تایید می کند:

 

Output

New Vault password: 
Confirm New Vault password:
Encryption successful

به جای باز کردن یک پنجره ویرایش، ansible-vault محتویات فایل را رمزگذاری می کند و آن را روی دیسک می نویسد و نسخه رمزگذاری نشده را جایگزین می کند.

اگر فایل را بررسی کنیم، باید یک الگوی رمزگذاری شده مشابه را ببینیم:

cat encrypt_me.txt

 

Output

$ANSIBLE_VAULT;1.1;AES256
66633936653834616130346436353865303665396430383430353366616263323161393639393136
3737316539353434666438373035653132383434303338640a396635313062386464306132313834
34313336313338623537333332356231386438666565616537616538653465333431306638643961
3636663633363562320a613661313966376361396336383864656632376134353039663662666437
39393639343966363565636161316339643033393132626639303332373339376664

همانطور که می بینید، Ansible محتوای موجود را به همان روشی که فایل های جدید را رمزگذاری می کند، رمزگذاری می کند.

مشاهده فایل های رمزگذاری شده

گاهی اوقات، ممکن است لازم باشد به محتویات یک فایل رمزگذاری شده بدون نیاز به ویرایش یا نوشتن آن در سیستم فایل بدون رمزگذاری، ارجاع دهید. دستور ansible-vault view محتویات یک فایل را به صورت استاندارد تغذیه می کند. به طور پیش فرض، این بدان معنی است که محتویات در ترمینال نمایش داده می شوند.

فایل رمزگذاری شده vault را به دستور ارسال کنید:

ansible-vault view vault.yml

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

 

Output

Vault password:
Secret information

همانطور که می بینید، درخواست رمز عبور در خروجی محتویات فایل مخلوط می شود. هنگام استفاده از نمای ansible-vault در فرآیندهای خودکار این را در نظر داشته باشید.

ویرایش فایل های رمزگذاری شده

هنگامی که نیاز به ویرایش یک فایل رمزگذاری شده دارید، از دستور ansible-vault edit استفاده کنید:

ansible-vault edit vault.yml

 

از شما رمز عبور فایل خواسته می شود. پس از وارد کردن آن، Ansible فایل را در یک پنجره ویرایش باز می کند، جایی که می توانید تغییرات لازم را انجام دهید.

پس از ذخیره، محتویات جدید با استفاده از رمز رمزگذاری فایل دوباره رمزگذاری شده و روی دیسک نوشته می شود.

رمزگشایی دستی فایل های رمزگذاری شده

برای رمزگشایی یک فایل رمزگذاری شده vault، از دستور ansible-vault decrypt استفاده کنید.

نام فایل رمزگذاری شده را ارسال کنید:

ansible-vault decrypt vault.yml

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

 

Output

Vault password:
Secret information

همانطور که می بینید، درخواست رمز عبور در خروجی محتویات فایل مخلوط می شود. هنگام استفاده از نمای ansible-vault در فرآیندهای خودکار این را در نظر داشته باشید.

ویرایش فایل های رمزگذاری شده

هنگامی که نیاز به ویرایش یک فایل رمزگذاری شده دارید، از دستور ansible-vault edit استفاده کنید:

ansible-vault edit vault.yml

از شما رمز عبور فایل خواسته می شود. پس از وارد کردن آن، Ansible فایل را در یک پنجره ویرایش باز می کند، جایی که می توانید تغییرات لازم را انجام دهید.

پس از ذخیره، محتویات جدید با استفاده از رمز رمزگذاری فایل دوباره رمزگذاری شده و روی دیسک نوشته می شود.

رمزگشایی دستی فایل های رمزگذاری شده

برای رمزگشایی یک فایل رمزگذاری شده vault، از دستور ansible-vault decrypt استفاده کنید.

نام فایل رمزگذاری شده را ارسال کنید:

ansible-vault decrypt vault.yml

از شما خواسته می شود رمز رمزگذاری فایل را وارد کنید. پس از وارد کردن رمز عبور صحیح، فایل رمزگشایی خواهد شد:

 

Output

Vault password:
Decryption successful

اگر دوباره فایل را مشاهده کنید، به جای رمزگذاری طاق، باید محتوای واقعی فایل را ببینید:

cat vault.yml

 

Output

Secret information

فایل شما اکنون روی دیسک رمزگذاری نشده است. پس از پایان کار، مطمئن شوید که اطلاعات حساس را حذف کرده یا فایل را دوباره رمزگذاری کنید.

تغییر رمز عبور فایل های رمزگذاری شده

اگر نیاز به تغییر رمز عبور یک فایل رمزگذاری شده دارید، از دستور ansible-vault rekey استفاده کنید:

ansible-vault rekey encrypt_me.txt

هنگامی که دستور را وارد می کنید، ابتدا رمز عبور فعلی فایل از شما خواسته می شود:

 

Output

Vault password:

پس از وارد کردن آن، از شما خواسته می شود رمز عبور جدید صندوق را انتخاب و تأیید کنید:

 

Output

Vault password:
New Vault password:
Confirm New Vault password:

هنگامی که رمز عبور جدید را با موفقیت تأیید کردید، پیامی مبنی بر موفقیت در فرآیند رمزگذاری مجدد دریافت خواهید کرد:

 

Output

Rekey successful

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

اجرای Ansible با فایل‌های رمزگذاری‌شده Vault

پس از اینکه اطلاعات حساس خود را با Vault رمزگذاری کردید، می توانید از فایل ها با ابزار معمولی Ansible استفاده کنید. دستورهای ansible و ansible-playbook هر دو می‌دانند چگونه فایل‌های محافظت‌شده در صندوق را با در نظر گرفتن رمز عبور صحیح رمزگشایی کنند. بسته به نیاز شما چند راه مختلف برای ارائه رمز عبور برای این دستورات وجود دارد.

برای پیگیری، به یک فایل رمزگذاری شده در طاق نیاز دارید. با تایپ کردن می توانید یکی ایجاد کنید:

ansible-vault create secret_key

رمز عبور را انتخاب و تأیید کنید. هر محتوای ساختگی را که می خواهید پر کنید:

secret_key

confidential data

ذخیره کنید و فایل را ببندید.

همچنین می توانیم یک فایل میزبان موقت به عنوان موجودی ایجاد کنیم:

nano hosts

ما فقط لوکال هاست Ansible را به آن اضافه می کنیم. برای آماده شدن برای مرحله بعدی، آن را در گروه [پایگاه داده] قرار می دهیم:

hosts

[database]
localhost ansible_connection=local

پس از اتمام کار فایل را ذخیره کرده و ببندید.

در مرحله بعد، یک فایل ansible.cfg در دایرکتوری فعلی ایجاد کنید، اگر قبلاً وجود نداشته باشد:

nano ansible.cfg

در حال حاضر، فقط یک بخش [پیش‌فرض] اضافه کنید و Ansible را به موجودی که ایجاد کردیم اضافه کنید:

ansible.cfg

[defaults]
inventory = ./hosts

وقتی آماده شدید، ادامه دهید.

استفاده از یک اعلان تعاملی

ساده ترین راه برای رمزگشایی محتوا در زمان اجرا این است که Ansible اعتبار مناسب را از شما بخواهد. می توانید این کار را با افزودن –ask-vault-pass به هر دستور ansible یا ansible-playbook انجام دهید. Ansible از شما رمز عبوری می خواهد که از آن برای رمزگشایی هر محتوای محافظت شده در خزانه که پیدا می کند استفاده می کند.

به عنوان مثال، اگر ما نیاز به کپی کردن محتویات یک فایل رمزگذاری شده در طاقچه در یک میزبان داشتیم، می‌توانیم این کار را با ماژول کپی و پرچم –ask-vault-pass انجام دهیم. اگر فایل واقعا حاوی داده های حساس است، به احتمال زیاد می خواهید دسترسی به میزبان راه دور را با محدودیت های مجوز و مالکیت قفل کنید.

ansible –ask-vault-pass -bK -m copy -a ‘src=secret_key dest=/tmp/secret_key mode=0600 owner=root group=root’ localhost

وظیفه ما مشخص می کند که مالکیت فایل باید به روت تغییر کند، بنابراین امتیازات مدیریتی مورد نیاز است. پرچم -bK به Ansible می گوید که رمز عبور sudo را برای میزبان مورد نظر درخواست کند، بنابراین از شما رمز عبور sudo خواسته می شود. سپس از شما رمز عبور Vault خواسته می شود:

 

Output

BECOME password:
Vault password:

هنگامی که رمز عبور ارائه می شود، Ansible تلاش می کند تا با استفاده از رمز عبور Vault برای هر فایل رمزگذاری شده ای که پیدا می کند، کار را اجرا کند. به خاطر داشته باشید که تمام فایل هایی که در حین اجرا به آنها ارجاع داده می شود باید از یک رمز عبور استفاده کنند:

 

Output

localhost | SUCCESS => {
    "changed": true, 
    "checksum": "7a2eb5528c44877da9b0250710cba321bc6dac2d", 
    "dest": "/tmp/secret_key", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "270ac7da333dd1db7d5f7d8307bd6b41", 
    "mode": "0600", 
    "owner": "root", 
    "size": 18, 
    "src": "/home/sammy/.ansible/tmp/ansible-tmp-1480978964.81-196645606972905/source", 
    "state": "file", 
    "uid": 0
}

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

استفاده از Ansible Vault با یک فایل رمز عبور

اگر نمی‌خواهید هر بار که کاری را انجام می‌دهید رمز عبور Vault را تایپ کنید، می‌توانید رمز عبور Vault خود را به یک فایل اضافه کنید و در حین اجرا به فایل ارجاع دهید.

به عنوان مثال، می توانید رمز عبور خود را در یک فایل .vault_pass مانند این قرار دهید:

echo ‘my_vault_password’ > .vault_pass

اگر از کنترل نسخه استفاده می کنید، مطمئن شوید که فایل رمز عبور را به فایل نادیده گرفتن نرم افزار کنترل نسخه خود اضافه کنید تا از انجام تصادفی آن جلوگیری کنید:

echo ‘.vault_pass’ >> .gitignore

اکنون می توانید به جای آن به فایل ارجاع دهید. پرچم –vault-password-file در خط فرمان موجود است. می‌توانیم همان کار را از قسمت آخر با تایپ کردن کامل کنیم:

ansible –vault-password-file=.vault_pass -bK -m copy -a ‘src=secret_key dest=/tmp/secret_key mode=0600 owner=root group=root’ localhost

این بار رمز عبور Vault از شما خواسته نمی شود.

خواندن خودکار فایل رمز عبور

برای جلوگیری از ارائه پرچم، می توانید متغیر محیطی ANSIBLE_VAULT_PASSWORD_FILE را با مسیر فایل رمز عبور تنظیم کنید:

export ANSIBLE_VAULT_PASSWORD_FILE=./.vault_pass

اکنون باید بتوانید دستور را بدون پرچم –vault-password-file برای جلسه جاری اجرا کنید:

ansible -bK -m copy -a ‘src=secret_key dest=/tmp/secret_key mode=0600 owner=root group=root’ localhost

برای آگاه کردن Ansible از محل فایل رمز عبور در جلسات، می توانید فایل ansible.cfg خود را ویرایش کنید.

فایل ansible.cfg محلی را که قبلا ایجاد کردیم باز کنید:

nano ansible.cfg

در بخش [defaults]، تنظیمات vault_password_file را تنظیم کنید. به محل فایل رمز عبور خود اشاره کنید. این می تواند یک مسیر نسبی یا مطلق باشد، بسته به اینکه کدام یک برای شما مفیدتر است:

ansible.cfg

[defaults]
. . .
vault_password_file = ./.vault_pass

اکنون، وقتی دستوراتی را اجرا می‌کنید که نیاز به رمزگشایی دارند، دیگر از شما خواسته نمی‌شود که پسورد vault را وارد کنید. به عنوان یک امتیاز، ansible-vault نه تنها از رمز عبور موجود در فایل برای رمزگشایی هر فایلی استفاده می کند، بلکه رمز عبور را هنگام ایجاد فایل های جدید با ایجاد ansible-vault و ensible-vault encrypt اعمال می کند.

خواندن رمز عبور از یک متغیر محیطی

ممکن است نگران ارسال تصادفی فایل رمز عبور خود به مخزن خود باشید. در حالی که Ansible یک متغیر محیطی برای اشاره به محل یک فایل رمز عبور دارد، اما متغیری برای تنظیم رمز عبور ندارد.

با این حال، اگر فایل رمز عبور شما قابل اجرا باشد، Ansible آن را به عنوان یک اسکریپت اجرا می کند و از خروجی به عنوان رمز عبور استفاده می کند. در یکی از مشکلات GitHub، برایان شویند پیشنهاد می کند که از اسکریپت زیر می توان برای استخراج رمز عبور از یک متغیر محیطی استفاده کرد.

فایل .vault_pass خود را در ویرایشگر خود باز کنید:

nano .vault_pass

اسکریپت زیر را جایگزین محتویات کنید:

.vault_pass

#!/usr/bin/env python3

import os
print os.environ['VAULT_PASSWORD']

فایل را با تایپ کردن قابل اجرا کنید:

chmod +x .vault_pass

سپس می توانید متغیر محیطی VAULT_PASSWORD را تنظیم و صادر کنید، که برای جلسه فعلی شما در دسترس خواهد بود:

export VAULT_PASSWORD=my_vault_password

شما باید این کار را در ابتدای هر جلسه Ansible انجام دهید، که ممکن است ناخوشایند به نظر برسد. با این حال، این کار به طور موثری از انجام تصادفی رمز عبور رمزگذاری Vault شما محافظت می کند، که می تواند اشکالات جدی داشته باشد.

استفاده از متغیرهای رمزگذاری شده در Vault با متغیرهای منظم

در حالی که Ansible Vault را می توان با فایل های دلخواه استفاده کرد، اغلب برای محافظت از متغیرهای حساس استفاده می شود. ما از طریق یک مثال کار خواهیم کرد تا به شما نشان دهیم که چگونه یک فایل متغیرهای معمولی را به پیکربندی تبدیل کنید که امنیت و قابلیت استفاده را متعادل می کند.

تنظیم مثال

برای این مثال، ما وانمود می کنیم که در حال پیکربندی یک سرور پایگاه داده هستیم، بدون اینکه در واقع نیاز به نصب پایگاه داده به عنوان پیش نیاز داشته باشیم.

زمانی که فایل هاست را زودتر ایجاد کردید، ورودی لوکال هاست را در گروهی به نام پایگاه داده قرار دادید تا برای این مرحله آماده شوید. پایگاه های داده معمولاً به ترکیبی از متغیرهای حساس و غیر حساس نیاز دارند. اینها را می توان در یک پوشه group_vars در فایلی به نام گروه اختصاص داد:

mkdir -p group_vars
nano group_vars/database

در داخل فایل group_vars/database، چند متغیر معمولی اضافه می کنیم. برخی از متغیرها، مانند شماره پورت MySQL، مخفی نیستند و می توانند آزادانه به اشتراک گذاشته شوند. سایر متغیرها، مانند رمز عبور پایگاه داده، محرمانه خواهند بود:

group_vars/database

---
# nonsensitive data
mysql_port: 3306
mysql_host: 10.0.0.3
mysql_user: fred

# sensitive data
mysql_password: supersecretpassword

می‌توانیم آزمایش کنیم که همه متغیرها با ماژول اشکال زدایی Ansible و متغیر hostvars در دسترس میزبان ما هستند:

ansible -m debug -a ‘var=hostvars[inventory_hostname]’ database

 

Output

localhost | SUCCESS => {
    "hostvars[inventory_hostname]": {
        "ansible_check_mode": false, 
        "ansible_version": {
            "full": "2.2.0.0", 
            "major": 2, 
            "minor": 2, 
            "revision": 0, 
            "string": "2.2.0.0"
        }, 
        "group_names": [
            "database"
        ], 
        "groups": {
            "all": [
                "localhost"
            ], 
            "database": [
                "localhost"
            ], 
            "ungrouped": []
        }, 
        "inventory_dir": "/home/sammy", 
        "inventory_file": "hosts", 
        "inventory_hostname": "localhost", 
        "inventory_hostname_short": "localhost", 
        "mysql_host": "10.0.0.3",
        "mysql_password": "supersecretpassword",
        "mysql_port": 3306,
        "mysql_user": "fred",
        "omit": "__omit_place_holder__1c934a5a224ca1d235ff05eb9bda22044a6fb400", 
        "playbook_dir": "."
    }
}

خروجی تأیید می کند که همه متغیرهایی که ما تنظیم کرده ایم روی هاست اعمال می شوند. با این حال، فایل group_vars/database ما در حال حاضر همه متغیرهای ما را در خود جای می دهد. این بدان معناست که ما می‌توانیم آن را رمزگذاری نشده رها کنیم، که به دلیل متغیر رمز پایگاه داده یک نگرانی امنیتی است، یا همه متغیرها را رمزگذاری کنیم، که باعث ایجاد مشکلاتی در قابلیت استفاده و همکاری می‌شود.

انتقال متغیرهای حساس به Ansible Vault

برای حل این موضوع باید بین متغیرهای حساس و غیر حساس تفاوت قائل شویم. ما باید بتوانیم مقادیر محرمانه را رمزگذاری کنیم و در عین حال به راحتی متغیرهای غیر حساس خود را به اشتراک بگذاریم. برای انجام این کار، متغیرهای خود را بین دو فایل تقسیم می کنیم.

به منظور اعمال متغیرهای بیش از یک فایل، می توان از یک فهرست متغیر به جای فایل متغیر Ansible استفاده کرد. ما می توانیم پیکربندی خود را برای استفاده از این توانایی تغییر دهیم. ابتدا نام فایل موجود را از پایگاه داده به vars تغییر دهید. این فایل متغیر رمزگذاری نشده ما خواهد بود:

mv group_vars/database group_vars/vars

بعد، یک دایرکتوری با همان نام فایل متغیر قدیمی ایجاد کنید. فایل vars را به داخل منتقل کنید:

mkdir group_vars/database
mv group_vars/vars group_vars/database/

ما اکنون به جای یک فایل، یک دایرکتوری متغیر برای گروه پایگاه داده داریم و یک فایل متغیر رمزگذاری نشده داریم. از آنجایی که متغیرهای حساس خود را رمزگذاری خواهیم کرد، باید آنها را از فایل رمزگذاری نشده خود حذف کنیم. برای حذف داده های محرمانه، فایل group_vars/database/vars را ویرایش کنید:

nano group_vars/database/vars

در این صورت می خواهیم متغیر mysql_password را حذف کنیم. اکنون فایل باید به شکل زیر باشد:

group_vars/database/vars

---
# nonsensitive data
mysql_port: 3306
mysql_host: 10.0.0.3
mysql_user: fred

سپس، یک فایل رمزگذاری شده با طاق در دایرکتوری ایجاد کنید که در کنار فایل vars رمزگذاری نشده زندگی می کند:

ansible-vault create group_vars/database/vault

در این فایل متغیرهای حساسی که قبلا در فایل vars وجود داشت را تعریف کنید. از نام متغیرهای یکسانی استفاده کنید، اما رشته vault_ را برای نشان دادن اینکه این متغیرها در فایل محافظت شده توسط vault تعریف شده اند، پیشاپیش قرار دهید:

group_vars/database/vault

---
vault_mysql_password: supersecretpassword

پس از اتمام کار فایل را ذخیره کرده و ببندید.

ساختار دایرکتوری حاصل به این صورت است:

.
├── . . .
├── group_vars/
│   └── database/
│       ├── vars
│       └── vault
└── . . .

در این مرحله، متغیرها جدا هستند و فقط داده های محرمانه رمزگذاری می شوند. این امن است، اما اجرای ما بر قابلیت استفاده ما تأثیر گذاشته است. در حالی که هدف ما محافظت از مقادیر حساس بود، همچنین ناخواسته دید را به نام متغیرهای واقعی کاهش دادیم. مشخص نیست که کدام متغیرها بدون ارجاع به بیش از یک فایل اختصاص داده شده اند، و در حالی که ممکن است بخواهید دسترسی به داده های محرمانه را در حین همکاری محدود کنید، هنوز احتمالاً می خواهید نام متغیرها را به اشتراک بگذارید.

برای پرداختن به این موضوع، پروژه Ansible به طور کلی رویکرد کمی متفاوت را توصیه می کند.

ارجاع به متغیرهای Vault از متغیرهای رمزگذاری نشده

هنگامی که ما داده های حساس خود را به فایل محافظت شده در طاق انتقال دادیم، نام متغیرها را با vault_ در پیش گفتیم (mysql_password تبدیل به vault_mysql_password شد). ما می توانیم نام متغیرهای اصلی (mysql_password) را به فایل رمزگذاری نشده اضافه کنیم. به‌جای تنظیم مستقیم این مقادیر روی مقادیر حساس، می‌توانیم از عبارات قالب‌بندی Jinja2 برای ارجاع نام متغیرهای رمزگذاری‌شده از داخل فایل متغیر رمزگذاری نشده خود استفاده کنیم. به این ترتیب، می توانید با ارجاع به یک فایل، همه متغیرهای تعریف شده را مشاهده کنید، اما مقادیر محرمانه در فایل رمزگذاری شده باقی می مانند.

برای نشان دادن، فایل متغیرهای رمزگذاری نشده را دوباره باز کنید:

nano group_vars/database/vars

دوباره متغیر mysql_password را اضافه کنید. این بار، از قالب Jinja2 برای ارجاع به متغیر تعریف شده در فایل محافظت شده از طاق استفاده کنید:

group_vars/database/vars

---
# nonsensitive data
mysql_port: 3306
mysql_host: 10.0.0.3
mysql_user: fred

# sensitive data
mysql_password: "{{ vault_mysql_password }}"

متغیر mysql_password به مقدار متغیر vault_mysql_password که در فایل vault تعریف شده تنظیم می شود.

با این روش می توانید با مشاهده فایل group_vars/database/vars، تمامی متغیرهایی را که بر روی هاست های گروه پایگاه داده اعمال می شود، درک کنید. قسمت های حساس توسط قالب Jinja2 محو می شوند. group_vars/database/vault تنها زمانی باید باز شود که خود مقادیر نیاز به مشاهده یا تغییر داشته باشند.

می توانید بررسی کنید تا مطمئن شوید که همه متغیرهای mysql_* هنوز به درستی با استفاده از همان روش دفعه قبل اعمال می شوند.

ansible -m debug -a ‘var=hostvars[inventory_hostname]’ database

 

Output

localhost | SUCCESS => {
    "hostvars[inventory_hostname]": {
        "ansible_check_mode": false, 
        "ansible_version": {
            "full": "2.2.0.0", 
            "major": 2, 
            "minor": 2, 
            "revision": 0, 
            "string": "2.2.0.0"
        }, 
        "group_names": [
            "database"
        ], 
        "groups": {
            "all": [
                "localhost"
            ], 
            "database": [
                "localhost"
            ], 
            "ungrouped": []
        }, 
        "inventory_dir": "/home/sammy/vault", 
        "inventory_file": "./hosts", 
        "inventory_hostname": "localhost", 
        "inventory_hostname_short": "localhost", 
        "mysql_host": "10.0.0.3",
        "mysql_password": "supersecretpassword",
        "mysql_port": 3306,
        "mysql_user": "fred",
        "omit": "__omit_place_holder__6dd15dda7eddafe98b6226226c7298934f666fc8", 
        "playbook_dir": ".", 
        "vault_mysql_password": "supersecretpassword"
    }
}

هم vault_mysql_password و هم mysql_password قابل دسترسی هستند. این تکرار بی ضرر است و تاثیری در استفاده شما از این سیستم نخواهد داشت.

نتیجه

پروژه های شما باید تمام اطلاعات مورد نیاز برای نصب و پیکربندی موفقیت آمیز سیستم های پیچیده را داشته باشند. با این حال، برخی از داده‌های پیکربندی طبق تعریف حساس هستند و نباید در معرض عموم قرار گیرند. در این راهنما، ما نشان دادیم که چگونه Ansible Vault می تواند اطلاعات محرمانه را رمزگذاری کند تا بتوانید تمام داده های پیکربندی خود را در یک مکان بدون به خطر انداختن امنیت نگه دارید.

Ansible VaultVPS یا سرور مجازیاتصال به لینوکسخرید سرور مجازیسرور اوبونتو 20.04سرور مجازیسرور مجازی آلمانسرور مجازی آمریکامتغیرهای Vault

 

 

https://vpsgol.net/product/vps-germany/

 

https://vpsgol.net/product/vps-usa/

 

https://vpsgol.net/product/vps-france/

 

https://vpsgol.net/product/vps-canada/

 

https://vpsgol.net/product/vps-poland/

 

https://vpsgol.net/product/vps-netherlands/

 

https://vpsgol.net/product/vps-england/

  • behnam gol mohamadi
  • ۰
  • ۰

نحوه استایل دادن به عناصر HTML با حاشیه ها، سایه ها و خطوط در CSS

ورود به سایت

معرفی

کار با سایه‌ها، حاشیه‌ها و خطوط کلی یکی از اجزای کلیدی توسعه وب است و می‌تواند تعریف بصری پیرامون عناصر HTML و آیتم‌های متنی ارائه دهد. ظاهر حاشیه ها و سایه ها را می توان از طریق پنج ویژگی اصلی CSS دستکاری کرد: border، border-radius، box-shadow، text-shadow و outline. سایه ها عمق را فراهم می کنند و به عناصر کمک می کنند تا برجسته شوند، در حالی که ویژگی های حاشیه می توانند عملکردهای بصری مختلفی را انجام دهند، از ایجاد یک تقسیم کننده خطی بین محتوا تا تعریف فضای یک شبکه. ویژگی border-radius گوشه های گردی را روی جعبه ها ایجاد می کند و حتی می تواند یک شکل دایره ای ایجاد کند. در نهایت، outline یک ویژگی است که اغلب نادیده گرفته می شود که بسیاری از عملکردهای مشابه ویژگی مرزی را بدون ایجاد اختلال در جریان محتوا ارائه می دهد.

در این آموزش، شما با این املاک کار خواهید کرد تا یک اعلامیه قانونی برای یک شرکت گردشگری فضایی خیالی ایجاد کنید. در طول نسخه ی نمایشی، با استفاده از ویژگی های مبتنی بر لبه، ظروف بصری غنی ایجاد خواهید کرد. علاوه بر این، تفاوت های ظریف در مورد مقادیر پیچیده تر، مانند سایه های متعدد و اینکه چگونه مرورگرهای مختلف می توانند ویژگی های خاص را به طور متفاوت پیاده سازی کنند را در نظر خواهید گرفت.

پیش نیازها

  • درک درستی از ویژگی‌های آبشار و ویژگی‌های CSS، که می‌توانید با خواندن نحوه اعمال سبک‌های CSS در HTML با Cascade و Specificity به آن دست پیدا کنید.
  • آشنایی با انتخابگرهای نوع، انتخابگرهای ترکیب‌کننده و گروه‌های انتخابگر، که می‌توانید در نحوه انتخاب عناصر HTML به سبک با CSS بیابید.
  • آشنایی با خواص رنگ در CSS برای اطلاعات بیشتر، نحوه استفاده از مقادیر رنگ با CSS را ببینید.
    آشنایی با گرادیان های CSS با ویژگی های پس زمینه. نحوه اعمال سبک‌های پس‌زمینه به عناصر HTML با CSS را بررسی کنید تا تجربه ایجاد پس‌زمینه گرادیان را به دست آورید.
  • یک فایل HTML خالی که در دستگاه محلی شما به عنوان index.html ذخیره شده است که می توانید از ویرایشگر متن و مرورگر وب انتخابی خود به آن دسترسی داشته باشید. برای شروع، آموزش نحوه تنظیم پروژه HTML خود را بررسی کنید و نحوه استفاده و درک عناصر HTML را برای دستورالعمل‌هایی در مورد نحوه مشاهده HTML خود در مرورگر خود دنبال کنید. اگر در HTML تازه کار هستید، کل نحوه ساخت یک وب سایت در سری HTML را امتحان کنید.

راه اندازی پایه HTML و CSS

در این بخش، پایه HTML را برای تمام سبک های بصری که در طول آموزش می نویسید، تنظیم می کنید. شما همچنین فایل styles.css خود را ایجاد کرده و سبک هایی را اضافه می کنید که طرح بندی محتوا را تنظیم می کند.

با باز کردن index.html در ویرایشگر متن خود شروع کنید. سپس HTML زیر را به فایل اضافه کنید:

index.html

<!doctype html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Travel Disclosure - Destination: Moon</title>
    <link href="styles.css" rel="stylesheet" />
  </head>
  <body>
  </body>
</html>

تنظیمات صفحه زیادی در عنصر <head> تعریف شده است. اولین عنصر <meta> مجموعه کاراکتری را برای استفاده از متن تعریف می کند. به این ترتیب اکثر کاراکترهای خاص، مانند علائم تاکیدی، بدون کدهای HTML خاص ارائه می شوند. عنصر دوم <meta> به مرورگرها و به ویژه مرورگرهای تلفن همراه می گوید که چگونه با عرض محتوا رفتار کنند. در غیر این صورت، مرورگر عرض دسکتاپ 960 پیکسلی را شبیه سازی می کند. عنصر <title> عنوان صفحه را در اختیار مرورگر قرار می دهد. عنصر <link> فایل CSS را بارگیری می کند که در آن استایل های خود را در طول این آموزش می نویسید.

صفحه همچنین برای استایل دادن به محتوا نیاز دارد. برای متن قانونی، شما از محتوای نمونه از Legal Ipsum به عنوان کپی پرکننده استفاده خواهید کرد که فقط برای اهداف طراحی در نظر گرفته شده است.

در ویرایشگر متن خود به index.html برگردید و HTML برجسته شده را از بلوک کد زیر اضافه کنید:

index.html

<!doctype html>
<html>
  ...
  <body>
    <section class="disclosure-alert">
      <header class="disclosure-header">
        <h2  class="disclosure-title"><em>Destination: Moon</em> Travel Disclosure</h2>
      </header>
      <div class="disclosure-content">
        <p>Although space travel is routine practice, there are many unknown possibilities that any traveller must be aware of before traveling with <em>Destination: Moon</em>. Agreeing to this disclosure of knowns is required prior to purchase of tickets with <em>Destination: Moon</em>. PLEASE, READ AND AGREE TO THE FOLLOWING DISCLOSURE OF TRAVEL UNKNOWNS BEFORE PROCEEDING TO PURCHASE.</p>
        <div class="legal-contents">
          <p>Effect of Termination. Upon termination, You agree not to use it under the terms of Sections 4(a) through 4(e) for that Covered Code, or any third party. Description of Modifications.<p>
          <p>You must make sure that you know you can do these things. To make sure the requirements of this Agreement. REQUIREMENTS A Contributor may participate in any way. Notwithstanding the foregoing, if applicable law or agreed to in writing, the Copyright Holder, but only to the terms applicable to Covered Code. Inability to Comply Due to Statute or Regulation.</p>
          <p>If it is impossible for You to the Recipient retains any such Additional Terms. Versions of This License. If you are re-using, b) a hyperlink (where possible) or URL to the terms of Sections 4(a) through 4(e) for that Work shall terminate if it fails to comply with the exception of content that is granting the License. License Terms 1.</p>
          <p>Grant of Patent Infringement. If you have knowledge of patent infringement litigation, then the only applicable Base Interpreter is a "commercial item" as defined in 48 C.F.R. Consistent with 48 C.F.R.</p>
          <p>U.S. Government End Users acquire Covered Code (Original Code and/or as part of a Larger Work; and b) allow the Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Distributor in writing of such Contributor, if any, to grant more extensive warranty protection to some or all of these conditions: (a) You must make it clear that any Modifications made by such Respondent, or (ii) withdraw Your litigation claim is resolved (such as Wikimedia-internal copying), it is Recipient's responsibility to secure any other exploitation. Program, and in any of the provisions set forth in Section 4(b), you shall terminate if it fails to comply with.</p>
          <p>Please note that these licenses do allow commercial uses of your company or organization, to others outside of this License Agreement), provided that You meet the following terms which differ from this License) and (b) You must duplicate the notice in Exhibit A in each changed file stating how and when you changed the files and the definitions are repeated for your past or future use of the Original Code; or 3) for infringements caused by: i) third party against the drafter will not be used as a handle): 1895.22/1011. This Agreement shall be held by the terms of this agreement. If any provision of this license which gives you legal permission to modify NetHack, or otherwise using this software in source and binary forms, with or without modification in printed materials or in related documentation, stating that you provide a service, including but not limited to the terms under which you distribute, wherever you describe the origin or ownership of such termination, the Recipient a non-exclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python 1.6b1 or any part of Derivative Works. If You initiate litigation by asserting a patent infringement against You in that instance.</p>
          <p>Effect of New York and the like. While this license document the following disclaimer in the Work contain all the conditions listed in Clause 6 above, concerning changes from the Work. If you created a Modification, you may at your option offer warranty protection to some or all of the Licensed Program as a product of your Modifications available to others outside of this License.</p>
          <p>Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted to Licensor for inclusion in the documentation and/or other rights consistent with this program; if not, write to the modified files to carry prominent notices stating that You distribute, all copyright, patent, trademark, and attribution notices from the Public Domain or from the Original Code; 2) separate from the Public Domain or from the Work, you may distribute a Compiled Work on their system exactly as it is being maintained, then ask the Current Maintainer to update their communication data within one month. If the program is free software; you can change the License will not have to defend and indemnify every other Contributor to control, and cooperate with the Source Code version of the Licensed Program, or any Contributor.</p>
        </div>
        <div class="button-group">
          <a href="#" class="button button-primary">
            Agree
          </a>
          <a href="#" class="button button-secondary">
            Disagree
          </a>
        </div>
      </div>
    </section>
  </body>
</html>

تغییرات خود را در index.html ذخیره کنید و سپس مرورگر وب خود را باز کنید. آیتم منوی File را انتخاب کنید و سپس گزینه Open را انتخاب کنید و فایل index.html خود را در مرورگر بارگذاری کنید. تصویر زیر نحوه نمایش این HTML در مرورگر را نشان می دهد:

یک فایل جدید به نام styles.css در همان دایرکتوری index.html ایجاد کنید، سپس آن را در ویرایشگر متن خود باز کنید. این فایل شامل تمام سبک های استفاده شده در طول آموزش است. اولین مجموعه از سبک ها یک زیبایی شناسی کلی را اعمال می کند که شما از آن خواهید ساخت. CSS را از بلوک کد زیر در فایل styles.css خود اعمال کنید:

styles.css

html, body {
  height: 100%;
}

body {
  display: flex;
  margin: 0;
  font: 100% / 1.5 sans-serif;
  background: url("images/moon-bg.jpg") no-repeat fixed center / cover black;
}
.disclosure-alert {
  background-color: hsl(0, 0%, 95%);
  width: 85%;
  max-width: 48rem;
  margin: auto;
  color: hsl(0, 0%, 20%);
}
.disclosure-header {
  background: linear-gradient(hsl(300, 50%, 20%), hsl(300, 50%, 10%));
  padding: 2rem 0.5rem;
  text-align: center;
  color: hsl(300, 50%, 95%);
}
.disclosure-title {
  margin: 0;
  font-size: 2rem;
  line-height: 1.25;
}
.disclosure-content {
  margin: 1.5rem;
}
.legal-contents {
  margin-top: 1.5rem;
  background-color: white;
  padding: 0.75rem;
  font-family: "Times New Roman", serif;
}
.button-group {
  margin-top: 1.5rem;
  display: flex;
  justify-content: center;
}
.button {
  display: inline-block;
  text-align: center;
  padding: 0.5rem 1rem;
  background: black;
  text-decoration: none;
  color: white;
  width: 50%;
  max-width: 8rem;
}
.button + .button {
  margin-left: 1.5rem;
}
.button-primary {
  background: linear-gradient(to bottom, hsl(200, 100%, 30%), hsl(200, 100%, 20%));
}
.button-primary:hover {
  background: linear-gradient(to bottom, hsl(200, 100%, 25%), hsl(200, 100%, 15%));
}
.button-secondary {
  background: linear-gradient(to bottom, hsl(200, 10%, 30%), hsl(200, 10%, 20%));
}
.button-secondary:hover {
  background: linear-gradient(to bottom, hsl(200, 10%, 25%), hsl(200, 10%, 15%));
}

استایل موجود در این فایل، طرح‌بندی اولیه صفحه را با افشای قانونی متمرکز، دکمه‌هایی با فاصله و رندر با گرادیان خطی، و تصویری از ماه به‌عنوان پس‌زمینه تنظیم می‌کند. قبل از ادامه، حتما فایل styles.css را ذخیره کنید.

برای نمایش تصویر پیوند شده در ویژگی پس‌زمینه مجموعه قوانین بدن، به تصویر پس‌زمینه ماه نیاز دارید. ابتدا یک پوشه images در همان پوشه فایل index.html خود بسازید:

mkdir images

از مرورگر خود برای دانلود این فایل در فهرست تصاویر جدید خود استفاده کنید یا از دستور curl زیر برای دانلود آن از طریق خط فرمان استفاده کنید:

curl -sL https://assets.digitalocean.com/articles/68102/moon-bg.jpg -o images/moon-bg.jpg

در مرحله بعد، به مرورگر خود بازگردید و آن را به روز کنید. مرورگر اکنون رندر و استایل ها را در محتوای صفحه اعمال می کند. تصویر زیر نحوه نمایش کامل صفحه را نشان می دهد:

طول محتوا باعث ایجاد یک صفحه بسیار طولانی می شود. از آنجایی که این به عنوان کپی قانونی در نظر گرفته شده است، محتوای .legal-contents می تواند به فضایی قابل پیمایش تبدیل شود. این کار از طریق ترکیبی از ویژگی های ارتفاع، حداکثر ارتفاع و سرریز انجام می شود.

برای ایجاد یک ناحیه قابل پیمایش، styles.css را در ویرایشگر متن خود باز کنید. سپس ارتفاع محتوای قانونی را با کد زیر تنظیم کنید:

styles.css

...
.legal-contents {
  height: 50vh;
  max-height: 20rem;
  overflow: auto;
  margin-top: 1.5rem;
  background-color: white;
  padding: 0.75rem;
  font-family: "Times New Roman", serif;
}
...

در این کد، یک ویژگی height را در بلوک انتخابگر محتوای قانونی ایجاد کردید، سپس مقدار آن را روی 50vh تنظیم کردید، یعنی 50 درصد از ارتفاع پنجره viewport. شما همچنین یک ویژگی max-height ایجاد کردید که مقدار آن روی 20rem تنظیم شده است. در نهایت، یک ویژگی سرریز با مقدار خودکار اضافه کردید، که در صورت سرریز شدن محتوا از ظرف، نوار اسکرول ایجاد می‌کند.

این موارد اضافه شده را در فایل styles.css خود ذخیره کنید، سپس به مرورگر خود بازگردید و index.html را بازخوانی کنید. ارتفاع کامل صفحه و ظرف اصلی متراکم شده است. اکنون، همانطور که در انیمیشن زیر نشان داده شده است، کپی Legal Ipsum را می توان در داخل ظرف تعیین شده خود پیمایش کرد:

در سراسر این بخش، HTML اصلی را تنظیم می کنید که برای بقیه آموزش استفاده خواهید کرد. شما همچنین یک فضای قابل پیمایش را با ویژگی overflow تنظیم می کنید. در قسمت بعدی با خاصیت border برای اعمال حاشیه بر روی این کانتینرها کار خواهید کرد.

با استفاده از مرز Property

ویژگی border یکی از روش های اصلی اعمال سبک ها در لبه های عناصر است. یک خط به هر رنگی در محیط بیرونی ظرف اعمال می کند. ارزش ملک از سه جزء تشکیل شده است: ضخامت، سبک و رنگ. ویژگی border این مقادیر را برای هر چهار طرف یک عنصر اعمال می کند. می‌توانید تک تک طرف‌ها را با تغییرات جهت حاشیه مشخص کنید، مانند ویژگی border-top، که فقط برای بالای یک عنصر اعمال می‌شود.

برای شروع کار با ویژگی border، styles.css را در ویرایشگر متن خود باز کنید و به انتخابگر کلاس .disclosure-alert بروید. در بلوک انتخابگر، همانطور که در بلوک کد زیر مشخص شده است، یک ویژگی مرزی با مقدار 1px solid hsl (0، 0٪، 0%) اضافه کنید:

styles.css

...
.disclosure-alert {
  background-color: hsl(0, 0%, 95%);
  width: 85%;
  max-width: 48rem;
  margin: auto;
  color: hsl(0, 0%, 20%);
  border: 1px solid hsl(0, 0%, 0%);
}
...

این ویژگی مرزی یک ویژگی مختصر است، یعنی مقدار آن ترکیبی از مقادیر دیگر است. در این مورد، ضخامت 1px مقدار خاصیت عرض حاشیه را نشان می دهد. این مقدار می تواند هر مقدار عددی با یک واحد همراه با چند مقدار نامگذاری شده باشد: نازک، متوسط و ضخیم. در مرحله بعد، solid مقدار به سبک مرزی است که نحوه ظاهر شدن خط اطراف عنصر را مشخص می کند، در این مورد به عنوان یک خط پیوسته و پیوسته. سایر مقادیر برای سبک حاشیه عبارتند از: نقطه چین، چین، دوتایی و هیچ. مقدار نهایی خاصیت border-color را مشخص می کند که می تواند هر مقدار رنگ معتبری باشد.

تغییرات خود را در styles.css ذخیره کنید، سپس index.html را در یک مرورگر وب باز کنید. محفظه محتوای اصلی اکنون دارای یک حاشیه سیاه نازک در اطراف خود خواهد بود، که بیشتر مشهود است زیرا تصویر پس‌زمینه ماه را پوشانده است. تصویر زیر نحوه نمایان شدن حاشیه در قسمت محتوای اصلی را نشان می دهد:

 

در مرحله بعد، می‌توانید از ویژگی border برای ایجاد حس عمق با اعمال برجسته‌ها و سایه‌ها به یک عنصر استفاده کنید. می توانید این کار را با استفاده از یک حاشیه جهت دار در یک طرف که از رنگ پس زمینه روشن تر است و سپس یک رنگ تیره تر در سمت مجاور انجام دهید.

در ویرایشگر متن خود به styles.css برگردید، سپس به بلوک انتخابگر کلاس .disclosure-header بروید. خطی-gradient() در ویژگی پس زمینه یک گرادیان بنفش تیره را تعریف می کند که به یک سایه کمی تیره تر تبدیل می شود. برای ایجاد عمق بیشتر از گرادیان به تنهایی، حاشیه را با کد زیر تنظیم کنید:

 

styles.css

 
...
.disclosure-header {
  background: linear-gradient(hsl(300, 50%, 20%), hsl(300, 50%, 10%));
  padding: 2rem 0.5rem;
  text-align: center;
  color: hsl(300, 50%, 95%);
  border-top: 1px solid hsl(300, 50%, 35%);
  border-bottom: 1px solid hsl(300, 50%, 5%);
}
...
 

شما یک ویژگی border-top با مقدار 1px solid hsl (300، 50٪، 35%) اضافه کردید، که کمی سبکتر از مقدار گرادیان شروع است. سپس، یک ویژگی حاشیه-پایین را با مقدار 1px solid hsl (300، 50٪، 5%) ایجاد کردید، که کمی تیره تر از انتهای گرادیان است.

تغییرات خود را در styles.css ذخیره کنید، سپس به مرورگر بازگردید و index.html را بازخوانی کنید. پس‌زمینه هدر بنفش اکنون کمی برجسته از رنگ بنفش در بالای سرصفحه و سایه‌ای جزئی در امتداد پایین دارد. تصویر زیر نشان می دهد که چگونه در مرورگر ظاهر می شود:

از آنجایی که border یک ویژگی مختصر است، می توانید ویژگی های longhand اضافی اضافه کنید. یک حاشیه می تواند اعمال شود که عرض و سبک دو کلاس دکمه را مشخص می کند، در حالی که یک رنگ حاشیه می تواند روی کلاس های جداگانه اعمال شود.

برای شروع کار با border-color، styles.css را در ویرایشگر متن خود باز کنید. در بلوک انتخاب کننده برای دکمه، یک ویژگی حاشیه با مقدار 1px جامد اضافه کنید، سپس یک ویژگی border-color برای .button-primary و .button-secondary اضافه کنید:

styles.css

...
.button {
  ...
  border: 1px solid;
}
...
.button-primary {
  background: linear-gradient(to bottom, hsl(200, 100%, 30%), hsl(200, 100%, 20%));
  border-color: hsl(200, 100%, 15%);
}
.button-primary:hover {
  background: linear-gradient(to bottom, hsl(200, 100%, 25%), hsl(200, 100%, 15%));
  border-color: hsl(200, 100%, 10%);
}
.button-secondary {
  background: linear-gradient(to bottom, hsl(200, 10%, 30%), hsl(200, 10%, 20%));
  border-color: hsl(200, 10%, 15%);
}
.button-secondary:hover {
  background: linear-gradient(to bottom, hsl(200, 10%, 25%), hsl(200, 10%, 15%));
  border-color: hsl(200, 10%, 10%);
}

این یک حاشیه به سبک جامد با عرض 1 پیکسل برای هر دو دکمه تعریف می کند. سپس، یک ویژگی حاشیه رنگ برای سفارشی کردن رنگ‌ها برای انتخابگرهای حالت .button-primary، .button-secondary و مرتبط با آنها اضافه کردید.

این تغییرات را در styles.css ذخیره کنید، سپس صفحه را در مرورگر وب خود بازخوانی کنید. همانطور که در تصویر زیر نشان داده شده است، دکمه‌ها اکنون با یک حاشیه رنگ تیره‌تر منطبق، تعریف کمی دارند:

در نهایت، هر جهت مرزی نیز مختصری است. این به این معنی است که -width، -style و -color هر کدام می‌توانند برای یک ویژگی جهت اعمال شوند. برای مثال، ویژگی longhand border-right-color فقط یک رنگ را در حاشیه سمت راست اعمال می کند.

برای کار با این ویژگی های حاشیه longhand جهت دار، در ویرایشگر متن خود به styles.css بازگردید. به بلوک انتخابگر .legal-contents بروید و عرض و سبک را برای هر چهار طرف حاشیه تنظیم کنید، سپس رنگ‌های هر طرف را سفارشی کنید:

styles.css

...
.legal-contents {
  height: 50vh;
  max-height: 20rem;
  margin-top: 1.5rem;
  overflow: auto;
  background-color: white;
  border: 1px solid;
  border-top-color: hsl(0, 0%, 65%);
  border-bottom-color: hsl(0, 0%, 100%);
  border-right-color: hsl(0, 0%, 80%);
  border-left-color: hsl(0, 0%, 80%);
  padding: 0.75rem;
  font-family: "Times New Roman", serif;
}
...

در این کد، حاشیه: 1px جامد را به انتهای فایل اضافه کردید. پس از آن، ویژگی های حاشیه-بالا-رنگ، رنگ حاشیه-پایین، رنگ حاشیه-راست-رنگ و رنگ حاشیه-چپ را نیز ایجاد کردید. برای مقادیر، از مقادیر مختلف hsl() برای خاکستری استفاده کردید.

تغییرات خود را در styles.css ذخیره کنید، سپس صفحه را دوباره در مرورگر بارگیری کنید. ظرف محتوی قابل پیمایش اکنون دارای یک حاشیه خاکستری تیره در امتداد بالا، خاکستری کمی روشن تر در طرفین و یک حاشیه سفید در پایین است. این برای این است که این تصور را ایجاد کنیم که محتوا در پشت پس‌زمینه خاکستری روشن قرار می‌گیرد و باعث ایجاد یک اثر می‌شود که برجسته‌سازی در لبه پایینی است، همانطور که در تصویر زیر نشان داده شده است:

در این قسمت از ویژگی border و تغییرات طولانی آن استفاده کردید. شما چندین حاشیه ایجاد کردید که در صورت نیاز به طرف های مختلف اعمال شد. در بخش بعدی، با ویژگی border-radius کار خواهید کرد که اجازه می دهد گوشه های کانتینرها گرد شوند.

اعمال یکborder-radius

گوشه‌های گرد مدت‌ها قبل از اینکه ویژگی حاشیه‌ای برای انجام این کار وجود داشته باشد، یک طراحی زیبایی‌شناسی در وب بوده است. این ویژگی می‌تواند هر واحد عددی یا مقدار درصدی را بپذیرد و یک ویژگی کوتاه‌نویسی مانند خواص حاشیه یا padding است. این بدان معنی است که هر گوشه را می توان به صورت جداگانه در صورت نیاز تنظیم کرد.

برای شروع کار با ویژگی border-radius، styles.css را در ویرایشگر متن خود باز کنید. به بلوک انتخابگر .disclosure-alert و ویژگی border-radius بروید. سپس، مقدار را روی 1.5rem قرار دهید، که این مقدار را در هر چهار گوشه ویژگی اعمال می کند. CSS هایلایت شده در بلوک کد زیر نشان می دهد که چگونه این نوشته شده است:

styles.css

...
.disclosure-alert {
  ...
  border: 1px solid hsl(0, 0%, 0%);
  border-radius: 1.5rem;
}
...

این افزونه را در styles.css ذخیره کنید و سپس index.html را در یک مرورگر وب باز کنید یا به‌روزرسانی کنید. فقط دو گوشه پایینی گرد به نظر می رسد، در حالی که دو گوشه بالایی لبه های نوک تیز باقی می مانند. تصویر زیر نشان می دهد که چگونه این در مرورگر رندر می شود:

 

دلیل اینکه فقط دو گوشه گرد قابل مشاهده است به دلیل نحوه تعامل عناصر نزولی با یکدیگر در وب است. مرورگر در نمایان نگه داشتن محتوا اشتباه می کند. .disclosure-alert دارای چهار گوشه گرد است، اما از آنجایی که .disclosure-header داخل عنصر است و گوشه‌های گرد ندارد، بر گوشه‌های گرد همپوشانی دارد. یک راه حل سریع اضافه کردن سرریز: مخفی به .disclosure-alert است که باعث می‌شود کانتینر هر ظروف و محتوای نزولی را حذف کند. با این حال، این رویکرد می تواند منجر به ناخوانا یا نامرئی شدن محتوای ضروری شود. یک تمرین بهتر این است که یک شعاع مرزی برای کلاس .disclosure-header اعمال کنید تا با منحنی گوشه اجداد خود مطابقت داشته باشد.

برای تنظیم گوشه های همپوشانی، به styles.css در ویرایشگر متن خود بازگردید. به بلوک انتخابگر .disclosure-header بروید و ویژگی border-radius را اضافه کنید. از آنجایی که فقط دو گوشه بالا نیاز به تنظیم دارند، مقدار 1.5rem 1.5rem 0 0 خواهد بود:

styles.css

...
.disclosure-header {
  ...
  border-top: 1px solid hsl(300, 50%, 35%);
  border-bottom: 1px solid hsl(300, 50%, 5%);
  border-radius: 1.5rem 1.5rem 0 0;
}
...

فرمت توسعه‌یافته این مقدار یک منحنی 1.5 میلی‌متری را در گوشه‌های بالا-چپ و بالا-راست اعمال می‌کند.

تغییرات خود را در styles.css ذخیره کنید و index.html را در مرورگر بازخوانی کنید. هدر بنفش اکنون گوشه ای گرد دارد و ظرف اصلی را نمی پوشاند. یک مشکل جدید ظاهر شده است، همانطور که در تصویر بزرگنمایی شده زیر نشان داده شده است، زیرا یک برش سفید از ظرف اصلی از پشت سرصفحه بنفش به اوج می رسد:

گوشه های هر دو .disclosure-alert و .disclosure-header به اندازه 1.5rem هستند، اما عرض آنها تفاوت اندازه دارند. این تفاوت اندازه ناشی از حاشیه سمت چپ و راست عنصر .disclosure-alert است. از آنجایی که عرض حاشیه در هر دو طرف 1px است، تفاوت اندازه آن 2px یا 0.125rem است. برای مطابقت دادن منحنی ها، شعاع مرزی برای .disclosure-header باید 0.125 rem کوچکتر از آنچه در حال حاضر است باشد. همانطور که در بلوک کد زیر مشخص شده است، مقادیر حاشیه 1.5rem را به 1.375rem تغییر دهید:

styles.css

...
.disclosure-header {
  background: linear-gradient(hsl(300, 50%, 20%), hsl(300, 50%, 10%));
  padding: 2rem 0.5rem;
  text-align: center;
  color: hsl(300, 50%, 95%);
  border-top: 1px solid hsl(300, 50%, 35%);
  border-bottom: 1px solid hsl(300, 50%, 5%);
  border-radius: 1.375rem 1.375rem 0 0;
}
...

این تغییر را در styles.css ذخیره کنید و سپس صفحه را در مرورگر وب بازخوانی کنید. برش سفید اکنون از بین رفته است و منحنی های دو عنصر در مکان مناسب به هم می رسند. تصویر بزرگنمایی شده زیر نشان می‌دهد که این منحنی‌ها چگونه کنار هم قرار می‌گیرند:

در نهایت، یک گوشه گرد روی دکمه های پایین ظرف اصلی اعمال می کنید. این دکمه ها به شکل قرص، با بالا و پایین صاف و بلند و کناره های کاملا گرد خواهند بود. برای انجام این کار، مقدار شعاع مرزی باید یک مقدار مبتنی بر واحد بزرگتر از ارتفاع عنصر باشد.

برای ایجاد دکمه ای به شکل قرص، styles.css را در ویرایشگر متن خود باز کنید. در بلوک انتخابگر دکمه، ویژگی border-radius را اضافه کنید و سپس مقدار را روی 2rem قرار دهید. این عدد می‌تواند یک عدد دلخواه باشد تا زمانی که بزرگتر از ارتفاع محاسبه‌شده، ترکیبی از اندازه قلم، ارتفاع خط، لایه‌بندی و عرض حاشیه باشد که می‌تواند بر ارتفاع کلی یک عنصر تاثیر بگذارد. CSS هایلایت شده در بلوک کد زیر نشان می دهد که کجا باید این ویژگی را اضافه کرد:

styles.css

...
.button {
  ...
  border: 1px solid;
  border-radius: 2rem;
}
...

در مورد این رویکرد دو نکته قابل ذکر است. اولین مورد این است که مقدار ارتفاع روی این عنصر تنظیم نشده است. از تنظیم مقدار ارتفاع باید اجتناب شود زیرا محتوا می تواند و در موقعیتی قرار می گیرد که خارج از ظرف جریان داشته باشد. با اجتناب از تعیین ارتفاع، دکمه می تواند رشد کند تا با کل محتوا مطابقت داشته باشد. دوم این است که با یک مقدار مبتنی بر درصد به درستی کار نخواهد کرد. مقادیر مبتنی بر درصد در ویژگی شعاع حاشیه، درصدی از ارتفاع و عرض را منحنی می‌کنند و به جای گوشه‌ای گرد، شکلی بیضی ایجاد می‌کنند.

تغییرات خود را در styles.css ذخیره کنید، سپس به مرورگر بازگردید و index.html را بازخوانی کنید. این صفحه اکنون دو دکمه مستطیلی به شکل قرص را نمایش می دهد، همانطور که در تصویر زیر نشان داده شده است:

در سرتاسر این بخش، شما از ویژگی border-radius برای اعمال گوشه های گرد به چندین عنصر استفاده کردید، و متوجه شدید که یک border-radius مانع از خروج عناصر نزولی از فضای منحنی نمی شود. شما همچنین مقدار شعاع حاشیه را طوری تنظیم کردید که با عرض یک عنصر مطابقت داشته باشد، زمانی که چندین عنصر گرد روی هم قرار می گیرند. در بخش بعدی، از ویژگی text-shadow برای اعمال سایه های در حال پخش بر روی محتوای متن استفاده می کنید.

با استفاده از ویژگی text-shadow

اعمال سایه روی متن کاربردهای زیادی در توسعه روزمره وب دارد. سایه‌ها می‌توانند عمق، جلوه درخشش ایجاد کنند، یا در مکان‌هایی که ممکن است نادیده گرفته شوند، به برجسته‌تر شدن متن کمک کنند. در سرتاسر این بخش، text-shadow را به چندین عنصر برای ایجاد جلوه های بصری مختلف اعمال می کنید.

ویژگی text-shadow حداکثر از چهار مقدار تشکیل شده است: offset محور x، offset محور y، blur radius و color. به عنوان مثال، مقادیر می توانند به این شکل باشند: 2px 4px 10px قرمز. از این چهار مقدار، فقط مقادیر افست مورد نیاز است. رنگ سایه به طور پیش فرض رنگ متن است.

برای شروع کار با text-shadow، با ایجاد یک افکت درخشش در هدر شروع می‌کنید. styles.css را در ویرایشگر متن خود باز کنید و به انتخابگر کلاس .disclosure-header بروید. در بلوک انتخابگر، ویژگی text-shadow زیر را اضافه کنید:

styles.css

...
.disclosure-header {
  ...
  border-radius: 1.375rem 1.375rem 0 0;
  text-shadow: 0 0 0.375rem hsl(300, 50%, 50%);
}
...

جلوه درخشش به این معنی است که رنگ از هر لبه متن بیرون می‌آید، بنابراین مقادیر افست محور x و y در اینجا روی 0 تنظیم می‌شوند. شما تاری برای درخشش را روی 0.375 rem (معادل 6 پیکسل) تنظیم می‌کنید تا کمی ظریف باشد. هاله رنگ به متن در نهایت، مقدار رنگ کمی تیره تر از ویژگی رنگ تنظیم شد: hsl (300، 50٪، 50%).

این افزودنی را در فایل styles.css خود ذخیره کنید. بعد، index.html را در یک مرورگر وب باز کنید. متن عنوان پررنگ در پس‌زمینه گرادیان بنفش اکنون درخششی از بنفش میانی در اطراف خود دارد. تصویر زیر نحوه نمایش این افکت در مرورگر را نشان می دهد:

در مرحله بعد، چندین سایه را می توان روی عناصر متن قرار داد، که امکان ایجاد یک جلوه برجسته روی متن را فراهم می کند. این افکت با قرار دادن یک سایه با رنگ روشن تر در زیر جسم و یک سایه با رنگ تیره در بالا انجام می شود.

برای ایجاد یک جلوه برجسته، به styles.css در ویرایشگر متن خود بازگردید. افکت به دکمه های پایین ظرف اضافه می شود. برای انتخابگرهای .button-primary، .button-primary:hover، .button-secondary و .button-secondary:hover یک ویژگی text-shadow اضافه کنید. CSS هایلایت شده را در بلوک کد زیر برای مقادیر بررسی کنید:

styles.css

...
.button-primary {
  border: 1px solid hsl(200, 100%, 5%);
  background: linear-gradient(to bottom, hsl(200, 100%, 30%), hsl(200, 100%, 20%));
  text-shadow: 0 1px hsl(200, 100%, 50%),
               0 -1px hsl(200, 100%, 5%);
}
.button-primary:hover {
  border: 1px solid hsl(200, 100%, 0%);
  background: linear-gradient(to bottom, hsl(200, 100%, 25%), hsl(200, 100%, 15%));
  text-shadow: 0 1px hsl(200, 100%, 45%),
               0 -1px hsl(200, 100%, 0%);
}
.button-secondary {
  border: 1px solid hsl(200, 10%, 5%);
  background: linear-gradient(to bottom, hsl(200, 10%, 30%), hsl(200, 10%, 20%));
  text-shadow: 0 1px hsl(200, 10%, 50%),
               0 -1px hsl(200, 10%, 5%);
}
.button-secondary:hover {
  border: 1px solid hsl(200, 10%, 0%);
  background: linear-gradient(to bottom, hsl(200, 10%, 25%), hsl(200, 10%, 15%));
  text-shadow: 0 1px hsl(200, 10%, 45%),
               0 -1px hsl(200, 10%, 0%);
}

سایه اول یک برجسته روشن تر از پایین است. این کار با آفست 0 1px و سپس نسخه روشن‌تر رنگ‌های گرادیان پس‌زمینه انجام می‌شود. در مرحله بعد، سایه بالای متن را با آفست 0 -1 پیکسل ایجاد کردید، که سایه را 1 پیکسل به بالا می کشد و از تنوع تیره تری از رنگ های پس زمینه استفاده می کند.

این تغییرات را در styles.css ذخیره کنید، سپس صفحه را در مرورگر وب خود بازخوانی کنید. اکنون متن داخل دکمه‌ها دارای یک برجسته‌سازی جزئی در زیر متن و یک سایه کمی در بالای متن است. ترکیب این مقادیر متن-سایه افکت برجسته را همانطور که در تصویر زیر ارائه می شود ایجاد می کند:

در این بخش، ویژگی text-shadow را روی چند عنصر اعمال کردید. شما یک افکت درخشش روی هدر و یک جلوه برجسته با سایه های متعدد روی دکمه ها ایجاد کردید. در بخش بعدی، سایه هایی را با ویژگی box-shadow به عناصر HTML اعمال می کنید.

افزودن box-shadow به عناصر

همانطور که ویژگی text-shadow به محتوای متن اجازه می دهد سایه داشته باشد، ویژگی box-shadow نیز به عناصر و کانتینرها اجازه می دهد سایه داشته باشند. box-shadow دارای دو ویژگی اضافی است که در این بخش بررسی خواهید کرد، از جمله توانایی کنترل گسترش تاری و تنظیم سایه در داخل عنصر.

برای شروع کار با ویژگی box-shadow، styles.css را در ویرایشگر متن خود باز کنید. در بلوک انتخابگر .disclosure-alert، ویژگی box-shadow را اضافه کنید. درست مانند text-shadow، مقادیر افست محور x و y مورد نیاز است و اگر رنگی ارائه نشده باشد، از مقدار ویژگی رنگ استفاده می شود. برای اولین کادر سایه، offset ها را روی 0، blur را روی 0.5rem، و رنگ را روی یک hsl تیره (300، 40٪، 5%) تنظیم کنید، همانطور که در بلوک کد زیر مشخص شده است:

styles.css

...
.disclosure-alert {
  ...
  border-radius: 1.5rem;
  text-shadow: 0 0 0.375rem hsl(300, 50%, 50%);
  box-shadow: 0 0 0.5rem hsl(300, 40%, 5%);
}
...

تغییرات را در styles.css ذخیره کنید و صفحه را در مرورگر وب خود بازخوانی کنید. اکنون یک سایه سیاه تقریباً از ظرف پخش شده است. همچنین توجه داشته باشید که سایه به منحنی هایی که با ویژگی border-radius ایجاد کرده اید احترام گذاشته و از آنها پیروی می کند. تصویر زیر نشان می دهد که چگونه این در مرورگر ارائه می شود:

در مرحله بعد، به styles.css بازگردید و با افزودن دو افکت درخشش بزرگ اضافی به box-shadow شروع به ایجاد یک افکت پیچیده تر کنید. بین هر سایه جدید یک کاما اضافه کنید، و هر کدام را به گونه‌ای تنظیم کنید که آفست محور y 0.5rem باشد. سپس تاری های بزرگ را تنظیم کنید و از تغییرات کم رنگ آبی و بنفش از پالت رنگ استفاده کنید، همانطور که در بلوک کد زیر مشخص شده است:

styles.css

...
.disclosure-alert {
  ...
  box-shadow: 0 0 0.5rem hsl(300, 40%, 5%),
              0 0.5rem 6rem hsl(200, 40%, 30%),
              0 0.5rem 10rem hsl(300, 40%, 30%);
}
...

ترتیب این سایه ها مهم است. اولین سایه با رنگ تقریبا مشکی در بالای سایه های جدید ارائه می شود و هر سایه بعدی پشت سایه بعدی اضافه می شود.

تغییرات خود را در styles.css ذخیره کنید و صفحه را در مرورگر خود بازخوانی کنید. همانطور که در تصویر زیر نشان داده شده است، ترکیب سایه های متعدد جلوه ای منحصر به فرد را ارائه می دهد:

ویژگی گسترش تاری ویژگی box-shadow را می توان برای ایجاد احساس عمق استفاده کرد. ارزش اسپرد هر دو ارزش مثبت و منفی را می پذیرد. گسترش ارزش منفی همراه با یک افست قوی و تاری سایه ای ایجاد می کند که دور و دور از ظرف منبع ایجاد می کند.

برای شروع، به styles.css در ویرایشگر متن خود بازگردید. بین سایه کوچک تیره و سایه آبی بزرگتر در انتخابگر .disclosure-alert، CSS هایلایت شده زیر را از بلوک کد اضافه کنید:

styles.css

...
.disclosure-alert {
  ...
  box-shadow: 0 0 0.5rem hsl(300, 40%, 5%),
              0 6rem 4rem -2rem hsl(300, 40%, 5%),
              0 0.5rem 6rem hsl(200, 40%, 30%),
              0 0.5rem 10rem hsl(300, 40%, 30%);
}
...

این اضافه شدن به مجموعه سایه، افست محور x را روی 0 نگه می دارد، اما محور y را به طور قابل توجهی به 6rem می رساند. بعد، تاری به اندازه درخشش بزرگ نیست، اما در اندازه مناسب 4 rem است. سپس به مقدار گسترش blur می رسد که در این حالت روی -2rem تنظیم می شود. مقدار پیش فرض اسپرد 0 است که برابر با ظرف است. در -2rem، گسترش از ظرف به سمت داخل متراکم می شود تا جلوه بصری عمق ایجاد کند.

تغییرات خود را در styles.css ذخیره کنید، سپس index.html را در مرورگر بازخوانی کنید. سایه یک رنگ بنفش تیره است که این حس را ایجاد می کند که جعبه محتوای اصلی به خوبی بالای سطح ماه شناور است، همانطور که در تصویر زیر نشان داده شده است:

یکی دیگر از موارد استفاده از box-shadow ایجاد یک هایلایت و افکت مخروطی سایه است، همانطور که قبلاً با ویژگی border در هدر انجام دادید. مزیت استفاده از box-shadow به جای حاشیه این است که بر مدل جعبه تأثیر نمی گذارد، که باعث تغییر در جریان محتوا می شود. همچنین می توان از آن در ارتباط با حاشیه استفاده کرد. هنگام استفاده از این افکت با حاشیه، مقدار inset باید به box-shadow اضافه شود تا سایه در داخل ظرف باشد.

برای شروع استفاده از مقدار inset در box-shadow، styles.css را در ویرایشگر متن خود باز کنید. این افکت به دکمه‌ها اضافه می‌شود، بنابراین شما این استایل‌ها را در .button-primary، .button-primary:hover، .button-secondary و .button-secondary:hover اعمال خواهید کرد. مانند text-shadow، این شامل یک ترکیب افست 0 1px و 0 -1px خواهد بود. تفاوت این است که کلمه inset را می توان به ابتدا یا انتهای مقدار اضافه کرد، همانطور که در بلوک کد زیر مشخص شده است:

styles.css

...
.button-primary {
  ...
  text-shadow: 0 1px hsl(200, 100%, 50%),
               0 -1px hsl(200, 100%, 5%);
  box-shadow: inset 0 1px hsl(200, 100%, 50%),
              inset 0 -1px hsl(200, 100%, 15%);
}
.button-primary:hover {
  ...
  text-shadow: 0 1px hsl(200, 100%, 45%),
               0 -1px hsl(200, 100%, 0%);
  box-shadow: inset 0 1px hsl(200, 100%, 45%),
              inset 0 -1px hsl(200, 100%, 10%);
}
.button-secondary {
  ...
  text-shadow: 0 1px hsl(200, 10%, 50%),
               0 -1px hsl(200, 10%, 5%);
  box-shadow: inset 0 1px hsl(200, 10%, 50%),
              inset 0 -1px hsl(200, 10%, 15%);
}
.button-secondary:hover {
  ...
  text-shadow: 0 1px hsl(200, 10%, 45%),
               0 -1px hsl(200, 10%, 0%);
  box-shadow: inset 0 1px hsl(200, 10%, 45%),
              inset 0 -1px hsl(200, 10%, 10%);
}

این تغییرات را در styles.css ذخیره کنید و سپس index.html را در مرورگر خود refresh کنید. اکنون دکمه ها دارای یک برجسته و یک سایه هستند، شبیه به متن. این ترکیب با پس‌زمینه گرادیان، جلوه‌ای ساده و در عین حال متمایز برای دکمه‌ها ایجاد می‌کند. تصویر زیر نشان می دهد که چگونه این در مرورگر ارائه می شود:

 

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

برای شروع ایجاد این افکت، styles.css را در ویرایشگر متن خود باز کنید. به انتخابگر کلاس .legal-contents بروید و یک ویژگی box-shadow اضافه کنید. این سایه از سه سایه تشکیل خواهد شد. اولی یک سایه کوتاه در اطراف داخل کل ظرف ایجاد می کند و دو مورد بعدی یک سایه روشن دراز در بالا و پایین عنصر ایجاد می کند. CSS هایلایت شده در بلوک کد زیر نحوه تنظیم این را نشان می دهد:

styles.css

...
.legal-contents {
  ...
  font-family: "Times New Roman", serif;
  box-shadow: 0 0 0.25rem hsl(0, 0%, 80%) inset,
              0 4rem 2rem -4rem hsl(0, 0%, 85%) inset,
              0 -4rem 2rem -4rem hsl(0, 0%, 85%) inset;
}
...

تغییرات خود را در styles.css ذخیره کنید، سپس صفحه را در مرورگر بازخوانی کنید. اکنون سایه‌ها جلوه‌ای ایجاد می‌کنند که باعث می‌شود متن قانونی مانند پنجره‌ای به داخل ظرف ظاهر شود. سایه ها همچنین به تقویت رنگ های حاشیه ای که روی این عنصر اعمال شده اند کمک می کند. تصویر زیر نشان می دهد که چگونه این در مرورگر رندر می شود:

در این قسمت ویژگی box-shadow را عملی می کنید. شما همچنین از ویژگی‌های پخش تاری و درج کردن جعبه سایه استفاده کردید تا گزینه‌های یک ظاهر طراحی بیشتری داشته باشید. در بخش آخر، ویژگی outline را پیاده سازی می کنید، سپس از box-shadow برای ایجاد یک طرح کلی همه کاره تر استفاده می کنید.

با استفاده از ویژگی طرح کلی

آخرین ویژگی که بر لبه های عناصر تأثیر می گذارد، ویژگی outline است. در تمام مرورگرها، حالت :focus عناصر با استفاده از ویژگی outline ساخته می‌شود. با این حال، اجرای سبک :focus پیش فرض هر مرورگر به طور قابل توجهی متفاوت است. ویژگی outline شبیه به ویژگی border است، به جز دو تفاوت کلیدی: تغییرات خاصیت جهت دار را ندارد و مدل جعبه را تحت تأثیر قرار نمی دهد. آخرین مورد از این دو تفاوت، آن را برای سبک‌های فوکوس ایده‌آل می‌کند، زیرا نشانگر بصری عنصر فعال را بدون ایجاد اختلال در جریان محتوا ارائه می‌کند.

برای مشاهده پیش فرض مرورگر حالت :focus، index.html را در مرورگر خود باز کنید. از کلید TAB برای پیمایش در صفحه استفاده کنید تا زمانی که یکی از دکمه های پایین فوکوس شود. بسته به اینکه از چه مرورگری استفاده می کنید، ممکن است نتوانید سبک های پیش فرض :focus را ببینید. به عنوان مثال، فایرفاکس یک طرح کلی با نقطه سفید را نشان می دهد، اما در پس زمینه خاکستری روشن قابل درک نیست. تصویر زیر از چپ به راست نشان می دهد که چگونه سبک فوکوس پیش فرض در فایرفاکس، سافاری و کروم ظاهر می شود:

برای شروع سفارشی کردن حالت :focus خود با ویژگی outline، styles.css را در ویرایشگر متن خود باز کنید. به انتخابگر کلاس .button بروید و ویژگی outline را اضافه کنید:

styles.css

...
.button {
  ...
}
.button:focus {
  outline: 0.25rem solid hsl(200, 100%, 50%);
}
...

همانند ویژگی border، مقدار طرح کلی شامل یک مقدار عرض، سبک و رنگ است. از آنجایی که هدف یک حالت فوکوس جلب توجه به یک عنصر است، عرض به 0.25rem افزایش می یابد که معادل 4px است. در مرحله بعد، استایل را روی حالت جامد قرار می دهید تا حالت فوکوس بیشتر شبیه سافاری و کروم باشد. در نهایت، رنگ را با hsl (200، 100، 50%) روی آبی تیره قرار می دهید.

تغییرات خود را در styles.css ذخیره کنید، سپس به مرورگر خود بازگردید و صفحه را بازخوانی کنید. یک بار دیگر، مرورگر نحوه نمایش طرح کلی را تعیین می کند. تصویر زیر نشان می دهد که این سبک ها در فایرفاکس، سافاری و کروم از چپ به راست چگونه هستند:

در هر سه مرورگر، ویژگی outline کاملاً متفاوت نمایش داده می شود. فایرفاکس دور کل شکل گرد دکمه را محکم نگه می دارد. سافاری یک کادر با زاویه راست ایجاد می کند، اما لبه های دکمه را لمس می کند. کروم شبیه سافاری است، اما فضای اضافی بین دکمه و طرح کلی اضافه می کند.

برای ایجاد سبکی که در همه مرورگرها شبیه به فایرفاکس باشد، به جای طرح کلی، باید از box-shadow استفاده کنید.

برای شروع ایجاد حالت :focus سفارشی تر، به فایل styles.css خود در ویرایشگر متن خود بازگردید. اولین کاری که باید انجام دهید این است که سبک طرح کلی پیش فرض مرورگر را با تغییر مقدار .button:focus نمایه انتخابگر به none غیرفعال کنید، همانطور که در بلوک کد زیر مشخص شده است:

styles.css

...
.button {
  ...
}
.button:focus {
  outline: none;
}
...

سپس، به انتخابگرهای button-primary:hover و button-secondary:hover بروید و یک کاما به دنبال آن یک تغییر حالت :focus اضافه کنید، همانطور که در بلوک کد زیر مشخص شده است:

styles.css

...

.button-primary {
  ...
}
.button-primary:hover,
.button-primary:focus {
  ...
}
.button-secondary {
  ...
}
.button-secondary:hover,
.button-secondary:focus {
  ...
}

در نهایت، دو انتخابگر جدید برای هر دکمه ایجاد کنید: فوکوس، .button-primary: focus، و .button-secondary:focus. در داخل بلوک‌های انتخابگر جدید، یک ویژگی box-shadow جدید با همان سایه‌های داخلی از همتای :hover، :focus آن‌ها اضافه کنید. سپس، سایه دیگری را با offset ها به مجموعه اضافه کنید و همه را روی 0 تار کنید. پس از آن، یک اسپرد 0.25rem اضافه کنید، که یک خط ثابت و غیر تار در اطراف عنصر ایجاد می کند. در نهایت رنگ یکسان را به هر دو نمونه اضافه کنید. CSS هایلایت شده در بلوک کد زیر نشان می دهد که چگونه این نوشته شده است:

styles.css

...

.button-primary {
  ...
}
.button-primary:hover,
.button-primary:focus {
  ...
}
.button-primary:focus {
  box-shadow: inset 0 1px hsl(200, 100%, 45%),
              inset 0 -1px hsl(200, 100%, 10%),
              0 0 0 0.25rem hsl(200, 100%, 50%);
}
.button-secondary {
  ...
}
.button-secondary:hover,
.button-secondary:focus<^> {
  ...
}
.button-secondary:focus {
  box-shadow: inset 0 1px hsl(200, 10%, 45%),
              inset 0 -1px hsl(200, 10%, 10%),
              0 0 0 0.25rem hsl(200, 100%, 50%);
}

این تغییرات را در styles.css ذخیره کنید و برای بازخوانی index.html به مرورگر خود بازگردید. اکنون، همانطور که از کلید TAB برای پیمایش در صفحه استفاده می کنید. صرف نظر از مرورگر، سبک :focus روی دکمه ها اکنون یکسان به نظر می رسد. تصویر زیر نشان می دهد که چگونه نسخه box-shadow یک طرح کلی به همراه کل صفحه در مرورگر ظاهر می شود:

این بخش آخر شما را با ویژگی outline و نحوه استفاده هر مرورگر از آن به روش های مختلف آشنا کرد. حداقل، یک نشانگر :focus برای دسترسی مورد نیاز است و ویژگی outline کار را انجام می دهد. با گسترش این موضوع، شما همچنین با ایجاد یک جعبه سایه با ارزش گسترش زیاد، یک سبک فوکوس پیشرفته‌تر و سازگارتر از نظر بصری ایجاد کردید.

نتیجه

سبک دادن به لبه های عناصر به طراحی یک وب سایت اجازه می دهد تا تنوع و توجه را به خود جلب کند. ویژگی border می تواند به ارائه تعریف و تفکیک بین محتوا کمک کند. ویژگی حاشیه-شعاع زیبایی شناسی را نرم می کند و به تعریف نگرش طرح کمک می کند. سایه های روی متن و جعبه ها عمق می بخشد و به جلب توجه به محتوا کمک می کند. در نهایت، ویژگی outline راه‌های در دسترس را برای جلب توجه به عناصر با فوکوس صفحه کلید فراهم می‌کند. در این آموزش، شما از تمام این ویژگی ها برای ایجاد یک صفحه وب از نظر بصری جالب و قابل استفاده استفاده کردید. درک هر یک از این ویژگی ها و نحوه و زمان استفاده از آنها به حل انواع مشکلات رابط فرانت اند و ایجاد تجربیات جدید کمک می کند.

 

 

https://vpsgol.net/product/vps-germany/

 

https://vpsgol.net/product/vps-usa/

 

https://vpsgol.net/product/vps-france/

 

https://vpsgol.net/product/vps-canada/

 

https://vpsgol.net/product/vps-poland/

 

https://vpsgol.net/product/vps-netherlands/

 

https://vpsgol.net/product/vps-england/

 

برچسب‌ها:CSSVPS یا سرور مجازیآشنایی با خواص رنگ در CSSایجاد سرور مجازیایجاد یکborder-radiusخرید سرور مجازیراه اندازی پایه HTMLراه اندازی پایه HTML و CSSسرورمجازیسرورمجازی آمریکا

  • behnam gol mohamadi
  • ۰
  • ۰

نحوه استفاده از Vuls به عنوان یک اسکنر آسیب پذیری در اوبونتو 18.04

ورود به سایت

معرفی

Vuls یک اسکنر آسیب‌پذیری منبع باز و بدون عامل است که در Go نوشته شده است. تجزیه و تحلیل آسیب پذیری امنیتی نرم افزار نصب شده بر روی یک سیستم را خودکار می کند، که می تواند برای مدیران سیستم به صورت دستی در یک محیط تولید کار سنگینی باشد. Vuls از چندین پایگاه داده آسیب‌پذیری معروف مانند پایگاه داده ملی آسیب‌پذیری (NVD) استفاده می‌کند. با توجه به منابع، Vuls این توانایی را دارد که چندین سیستم را به طور همزمان اسکن کند و گزارش ها را از طریق ایمیل یا Slack ارسال کند. دارای سه حالت اسکن (سریع، سریع روت و عمیق) است که می توانید با توجه به شرایط آن را انتخاب کنید.

Vuls یک اسکنر امنیتی فناوری اطلاعات گسترده نیست. به عنوان مثال، ترافیک شبکه را کنترل نمی کند یا در برابر حملات brute-force لاگین محافظت نمی کند. با این حال، Vuls راهی برای خودکار کردن گزارش آسیب‌پذیری برای بسته‌های لینوکس ارائه می‌کند. هنگامی که پایگاه‌های داده‌ای که Vuls استفاده می‌کند از رفع آسیب‌پذیری‌های خاص مطلع می‌شوند، Vuls این اطلاعات اصلاحی را نیز در گزارش‌های خود می‌آورد. هنگام تولید گزارش ها، Vuls با استفاده از سیستم رتبه بندی ایجاد شده از پایگاه داده، فوری ترین آسیب پذیری ها را اولویت بندی می کند.

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

پیش نیازها

برای تکمیل این آموزش، شما نیاز دارید:

  • سروری با حداقل 2 گیگابایت رم که اوبونتو 18.04 را با دسترسی روت اجرا می کند و یک حساب ثانویه غیر روت.
  • فضای کاری Slack که شما عضو آن هستید.
  • (اختیاری) چندین سرور در حال اجرا (ترجیحا) Ubuntu 18.04 با دسترسی ریشه و یک حساب ثانویه و غیر ریشه، اگر می‌خواهید Vuls را برای اسکن از راه دور تنظیم کنید.

مرحله 1 – نصب Dependencies

در این بخش، پوشه ای برای ذخیره داده های Vuls ایجاد می کنید، آخرین نسخه زبان برنامه نویسی Go را نصب می کنید و سایر بسته های مورد نیاز Vuls و وابستگی های آن را نصب می کنید.

برای این آموزش، تمام داده های مربوط به Vuls را در پوشه /usr/share/vuls-data ذخیره می کنید. با اجرای دستور زیر آن را ایجاد کنید:

sudo mkdir /usr/share/vuls-data

برای دسترسی به سامی، دستور زیر را اجرا کنید:

sudo chown -R sammy /usr/share/vuls-data

اکنون پوشه vuls-data را ایجاد کرده اید که فضای کاری شما خواهد بود. قبل از ادامه نصب بسته‌های مورد نیاز، ابتدا حافظه پنهان بسته منیجر را به‌روزرسانی کنید:

sudo apt update

برای دانلود و کامپایل وابستگی ها، git، gcc، make، sqlite، debian-goodies و wget را نصب خواهید کرد.

sqlite یک سیستم پایگاه داده است که در اینجا برای ذخیره اطلاعات آسیب پذیری از آن استفاده خواهید کرد. debian-goodies حاوی ابزار checkrestart است که اطلاعاتی را در مورد اینکه چه بسته هایی می توانند و باید در هر لحظه از زمان راه اندازی مجدد شوند را ارائه می دهد.

شما می توانید همه آنها را در یک دستور نصب کنید:

sudo apt install sqlite git debian-goodies gcc make wget -y

اکنون بسته های مورد نیاز را نصب کرده اید. سپس با اجرای دستور زیر، Go را با استفاده از مدیریت بسته snap نصب کنید:

sudo snap install go –classic

شما از snap برای نصب Go استفاده می‌کنید زیرا آخرین نسخه زبان را نصب می‌کند، برخلاف apt، که ممکن است نسخه قدیمی‌تر را نصب کند. کار با نسخه قدیمی توصیه نمی شود و ممکن است شما را از تکمیل این آموزش باز دارد.

برای کار کردن، Go به چند متغیر محیطی نیاز دارد که شما آنها را تنظیم خواهید کرد: GOPATH و PATH. GOPATH دایرکتوری کاری Go را مشخص می کند. PATH که شامل دایرکتوری هایی است که برنامه ها در آنها قرار می گیرند، باید گسترش یابد تا به سیستم بگوید که خود Go را کجا پیدا کند.

این متغیرهای محیطی باید هر بار که کاربر وارد سیستم می شود تنظیم شود. برای خودکار کردن این کار، یک فایل اجرایی جدید به نام go-env.sh در زیر /etc/profile.d ایجاد خواهید کرد. این باعث می شود که هر بار که کاربر وارد می شود دایرکتوری اجرا شود.

go-env.sh را با استفاده از ویرایشگر متن خود ایجاد کنید:

sudo nano /etc/profile.d/go-env.sh

دستورات زیر را به فایل اضافه کنید:

/etc/profile.d/go-env.sh

export GOPATH=$HOME/go
export PATH=$PATH:$GOPATH/bin:/snap/bin

دستور صادرات متغیر محیطی داده شده را به مقدار دلخواه تنظیم می کند. در اینجا شما از آن برای پر کردن GOPATH و PATH با مقادیر مناسب استفاده می کنید.

ذخیره کنید و فایل را ببندید.

در حال حاضر، go-env.sh قابل اجرا نیست. برای رفع این مشکل، با اجرای دستور زیر آن را به عنوان قابل اجرا علامت گذاری کنید:

sudo chmod +x /etc/profile.d/go-env.sh

برای جلوگیری از ورود مجدد به سیستم، می توانید go-env.sh را با اجرای:

source /etc/profile.d/go-env.sh

دستور منبع فایل داده شده را در پوسته فعلی بارگذاری مجدد می کند در حالی که حالت آن را حفظ می کند.

در این بخش، زبان Go را نصب کرده‌اید، متغیرهای محیطی آن را تنظیم کرده‌اید و بسته‌هایی را نصب کرده‌اید که بعداً به آنها نیاز خواهید داشت. در مراحل بعدی، برنامه های Go را که Vuls نیاز دارد دانلود و کامپایل خواهید کرد. این برنامه‌ها go-cve-dictionary و goval-dictionary هستند که Vuls از آنها برای جستجو در پایگاه‌های داده آسیب‌پذیری استفاده می‌کند.

مرحله 2 – نصب و اجرای go-cve-dictionary

در این بخش، go-cve-dictionary را دانلود و کامپایل می‌کنید، یک بسته Go که دسترسی به NVD (پایگاه ملی آسیب‌پذیری) را فراهم می‌کند. سپس، آن را اجرا می‌کنید و داده‌های آسیب‌پذیری را برای Vuls واکشی می‌کنید تا از آن استفاده کند. NVD مخزن آسیب‌پذیری‌های امنیت سایبری گزارش‌شده عمومی توسط دولت ایالات متحده است که حاوی شناسه‌های آسیب‌پذیری (CVE – آسیب‌پذیری‌های رایج و مواجهه‌ها)، خلاصه‌ها و تجزیه و تحلیل تأثیر است و در قالب قابل خواندن توسط ماشین در دسترس است.

برو بسته‌ها را تحت $GOPATH/src/ ذخیره می‌کند. شما می توانید این را با استفاده از زیر شاخه ها برای یادداشت مبدا گسترش دهید. به عنوان مثال، بسته‌های GitHub که توسط کاربر مثال کاربر ساخته شده است، در $GOPATH/src/github.com/example-user ذخیره می‌شوند.

ابتدا go-cve-dictionary را با شبیه سازی بسته Go از GitHub و سپس کامپایل کردن آن نصب خواهید کرد.

با ایجاد یک دایرکتوری برای ذخیره آن، مطابق مسیر مثال، شروع کنید:

mkdir -p $GOPATH/src/github.com/vulsio

با اجرای زیر به آن بروید:

cd $GOPATH/src/github.com/vulsio

اکنون با اجرای:

git clone https://github.com/vulsio/go-cve-dictionary.git

سپس به ریشه بسته بروید:

cd go-cve-dictionary

در نهایت با اجرای دستور زیر آن را کامپایل و نصب کنید:

make install

به خاطر داشته باشید که اتمام این دستور ممکن است کمی طول بکشد. برای در دسترس قرار دادن آن در سطح سیستم، آن را در /usr/local/bin کپی کنید:

sudo cp $GOPATH/bin/go-cve-dictionary /usr/local/bin

go-cve-dictionary نیاز به دسترسی به دایرکتوری خروجی log دارد و به طور پیش فرض /var/log/vuls است. آن را با اجرا ایجاد کنید:

sudo mkdir /var/log/vuls

در حال حاضر، دایرکتوری گزارش برای همه قابل خواندن است. با دستور زیر دسترسی کاربر فعلی را محدود کنید:

sudo chmod 700 /var/log/vuls

در حال حاضر، دایرکتوری گزارش برای همه قابل خواندن است. با دستور زیر دسترسی کاربر فعلی را محدود کنید:

sudo chmod 700 /var/log/vuls

تنظیم پرچم های مجوز روی 700 دسترسی فقط به مالک را محدود می کند.

برای اینکه سامی یا کاربر دیگری به آن دسترسی داشته باشد، دستور زیر را اجرا کنید:

sudo chown -R sammy /var/log/vuls

اکنون، داده‌های آسیب‌پذیری را از NVD دریافت کرده و در فضای کاری Vuls خود ذخیره می‌کنید (/usr/share/vuls-data):

go-cve-dictionary fetch nvd –dbpath /usr/share/vuls-data/cve.sqlite3

این دستور داده‌های آسیب‌پذیری NVD را از سال 2002 تا سال جاری دریافت می‌کند و آن‌ها را در پایگاه داده تحت /usr/share/vuls-data ذخیره می‌کند.

در این مرحله، go-cve-dictionary را دانلود و نصب کرده‌اید و داده‌های NVD را برای Vuls برای استفاده بعدی واکشی کرده‌اید. در بخش بعدی، goval-dictionary را دانلود و نصب می‌کنید و داده‌های OVAL را برای اوبونتو واکشی می‌کنید.

مرحله 3 – نصب و اجرای Goval-Dictionary

در این بخش، goval-dictionary را دانلود و کامپایل می‌کنید، یک بسته Go که دسترسی به پایگاه داده OVAL را برای اوبونتو فراهم می‌کند. سپس آن را اجرا می‌کنید و داده‌های آسیب‌پذیری را برای استفاده Vuls واکشی می‌کنید. OVAL مخفف Open Vulnerability and Assessment Language است که یک زبان باز است که برای بیان بررسی‌ها برای تعیین اینکه آیا آسیب‌پذیری‌های نرم‌افزاری در یک سیستم خاص وجود دارد یا خیر استفاده می‌شود.

به پوشه $GOPATH/src/github.com/vulsio بروید:

cd $GOPATH/src/github.com/vulsio

با اجرای دستور زیر بسته را از GitHub کلون کنید:

git clone https://github.com/vulsio/goval-dictionary.git

وارد پوشه بسته شوید:

cd goval-dictionary

آن را با make کامپایل و نصب کنید:

make install

برای دسترسی جهانی آن را در /usr/local/bin کپی کنید:

sudo cp $GOPATH/bin/goval-dictionary /usr/local/bin

سپس، با اجرای دستور زیر، داده های OVAL را برای Ubuntu 18.x واکشی کنید:

sudo goval-dictionary fetch ubuntu –dbpath=/usr/share/vuls-data/oval.sqlite3 18

در این مرحله، goval-dictionary را دانلود و نصب کرده اید و داده های OVAL را برای Ubuntu 18.x واکشی کرده اید. در مرحله بعدی، gost را دانلود و نصب می‌کنید و داده‌های ردیاب امنیتی Debian را واکشی می‌کنید.

مرحله 4 – نصب و اجرای gost

در این بخش، gost را دانلود و کامپایل می‌کنید، بسته Go که دسترسی به ردیاب اشکال امنیتی دبیان را فراهم می‌کند. سپس آن را اجرا می‌کنید و داده‌های آسیب‌پذیری را برای Vuls واکشی می‌کنید تا از آن استفاده کند. ردیاب امنیتی اوبونتو تمام اطلاعات مربوط به وضعیت آسیب پذیری بسته های توزیع شده با اوبونتو را جمع آوری می کند.

این بسته را در همان دایرکتوری قبلی ذخیره خواهید کرد. با اجرای دستور زیر به آن بروید:

cd $GOPATH/src/github.com/vulsio

با اجرای زیر بسته را از GitHub کلون کنید:

git clone https://github.com/vulsio/gost.git

پس از اتمام، پوشه بسته را وارد کنید:

cd gost

آن را با make کامپایل و نصب کنید:

make install

برای دسترسی جهانی آن را در /usr/local/bin کپی کنید:

sudo cp $GOPATH/bin/gost /usr/local/bin

سپس یک فهرست فایل log برای gost ایجاد کنید:

sudo mkdir /var/log/gost

با دستور زیر دسترسی کاربر فعلی را محدود کنید:

sudo chmod 700 /var/log/gost

همانطور که قبلاً ذکر شد، تنظیم پرچم های مجوز روی 700 دسترسی فقط به مالک را محدود می کند.

برای اینکه سامی یا کاربر دیگری به آن دسترسی داشته باشد، دستور زیر را اجرا کنید:

sudo chown -R sammy /var/log/gost

سپس، داده‌های ردیاب امنیتی اوبونتو را با اجرای زیر واکشی کنید:

gost fetch ubuntu –dbpath=/usr/share/vuls-data/gost.sqlite3

خروجی طولانی خواهد بود و احتمالاً به درستی پاک نمی شود. برای پاک کردن آن می توانید دستور clear را اجرا کنید.

در این مرحله شما gost را دانلود و نصب کرده اید و داده ها را برای دبیان واکشی کرده اید. در مرحله بعد، Vuls را دانلود و نصب خواهید کرد.

مرحله 5 – دانلود و پیکربندی Vuls

با نصب تمام وابستگی ها، اکنون Vuls را از کد منبع دانلود و کامپایل خواهید کرد. پس از آن، آن را برای اسکن ماشین محلی پیکربندی خواهید کرد.

با این دستور یک دایرکتوری جدید ایجاد کنید که حاوی مسیر مخزن Vuls باشد:

mkdir -p $GOPATH/src/github.com/future-architect

به آن بروید:

cd $GOPATH/src/github.com/future-architect

با اجرای دستور زیر، Vuls را از GitHub کلون کنید:

git clone https://github.com/future-architect/vuls.git

وارد پوشه بسته شوید:

cd vuls

کامپایل و همزمان با اجرای:

make install

به یاد داشته باشید که ممکن است مدتی طول بکشد تا این دستور کامل شود.

برای دسترسی جهانی آن را در /usr/local/bin کپی کنید:

sudo cp $GOPATH/bin/vuls /usr/local/bin

اکنون، یک فایل پیکربندی برای Vuls ایجاد خواهید کرد. به /usr/share/vuls-data برگردید:

cd /usr/share/vuls-data

Vuls پیکربندی خود را در یک فایل TOML ذخیره می کند که شما آن را config.toml می نامید. آن را با استفاده از ویرایشگر متن خود ایجاد کنید:

sudo nano config.toml

پیکربندی زیر را وارد کنید:

/usr/share/vuls-data/config.toml

[cveDict]
type = "sqlite3"
SQLite3Path = "/usr/share/vuls-data/cve.sqlite3"

[ovalDict]
type = "sqlite3"
SQLite3Path = "/usr/share/vuls-data/oval.sqlite3"

[gost]
type = "sqlite3"
SQLite3Path = "/usr/share/vuls-data/gost.sqlite3"

[servers]

[servers.localhost]
host = "localhost"
port = "local"
scanMode = [ "fast" ]
#scanMode = ["fast", "fast-root", "deep", "offline"]

 

دو بخش اول این پیکربندی (cveDict و ovalDict) Vuls را به پایگاه‌های آسیب‌پذیری که در دو مرحله آخر ایجاد کردید، نشان می‌دهند. بخش بعدی (سرورها) شروع اطلاعات مربوط به سرور را نشان می دهد. بخش های جداگانه اطلاعات مربوط به هر سرور را گروه بندی می کند. تنها سروری که Vuls با این پیکربندی مشخص شده اسکن می‌کند، سرور محلی (localhost) است.

Vuls چهار حالت اسکن را ارائه می دهد:

  • حالت سریع (پیش‌فرض): بدون دسترسی ریشه اسکن می‌کند، وابستگی ندارد و روی سرور مورد نظر بسیار سبک است.
  • حالت ریشه سریع: با امتیازات ریشه اسکن می کند و می تواند فرآیندهای ارتقا یافته، اما هنوز راه اندازی مجدد نشده را شناسایی کند.
  • حالت اسکن عمیق: مانند حالت روت سریع، اما تغییرات لاگ را بررسی می کند، که می تواند منجر به بار زیاد روی سرور مورد نظر شود.
  • حالت آفلاین: دستگاه را بدون دسترسی به اینترنت اسکن می کند و می تواند همراه با حالت های دیگر استفاده شود.
    ذخیره کنید و فایل را ببندید.

برای تست اعتبار فایل پیکربندی، دستور زیر را اجرا کنید:

vuls configtest

خروجی شبیه به این خواهد بود:

 

Output

[Dec 14 09:07:28]  INFO [localhost] vuls-v0.19.0-build-20211214_090234_2b7294a
[Dec 14 09:07:28]  INFO [localhost] Validating config...
[Dec 14 09:07:28]  INFO [localhost] Detecting Server/Container OS...
[Dec 14 09:07:28]  INFO [localhost] Detecting OS of servers...
[Dec 14 09:07:28]  INFO [localhost] (1/1) Detected: localhost: ubuntu 18.04
[Dec 14 09:07:28]  INFO [localhost] Detecting OS of containers...
[Dec 14 09:07:28]  INFO [localhost] Checking Scan Modes...
[Dec 14 09:07:28]  INFO [localhost] Checking dependencies...
[Dec 14 09:07:28]  INFO [localhost] Dependencies... Pass
[Dec 14 09:07:28]  INFO [localhost] Checking sudo settings...
[Dec 14 09:07:28]  INFO [localhost] sudo ... No need
[Dec 14 09:07:28]  INFO [localhost] It can be scanned with fast scan mode even if warn or err messages are displayed due to lack of dependent packages or sudo settings in fast-root or deep scan mode
[Dec 14 09:07:28]  INFO [localhost] Scannable servers are below...
localhost

شما پیکربندی را به درستی وارد کرده اید و Vuls تشخیص داده است که می تواند سرور محلی را اسکن کند.

شما Vuls را برای اسکن سرور محلی نصب و پیکربندی کرده اید. در مرحله بعد اسکن محلی را اجرا کرده و گزارش تولید شده را مشاهده خواهید کرد.

مرحله 6 – اجرای یک اسکن محلی

در این بخش، یک اسکن محلی را اجرا کرده و سپس گزارش آسیب‌پذیری ایجاد شده را مشاهده خواهید کرد. در حال حاضر، شما فقط سرور محلی را پیکربندی کرده اید که Vuls در مرحله آخر به درستی آن را شناسایی کرده است. حالت اسکن پیش فرض، اگر به صراحت مشخص نشده باشد، سریع است.

برای اجرای اسکن، دستور زیر را اجرا کنید:

vuls scan

خروجی شبیه به این خواهد بود:

[Dec 14 09:07:47]  INFO [localhost] vuls-v0.19.0-build-20211214_090234_2b7294a
[Dec 14 09:07:47]  INFO [localhost] Start scanning
[Dec 14 09:07:47]  INFO [localhost] config: /usr/share/vuls-data/config.toml
[Dec 14 09:07:47]  INFO [localhost] Validating config...
[Dec 14 09:07:47]  INFO [localhost] Detecting Server/Container OS...
[Dec 14 09:07:47]  INFO [localhost] Detecting OS of servers...
[Dec 14 09:07:47]  INFO [localhost] (1/1) Detected: localhost: ubuntu 18.04
[Dec 14 09:07:47]  INFO [localhost] Detecting OS of containers...
[Dec 14 09:07:47]  INFO [localhost] Checking Scan Modes...
[Dec 14 09:07:47]  INFO [localhost] Detecting Platforms...
[Dec 14 09:07:47]  INFO [localhost] (1/1) localhost is running on other
[Dec 14 09:07:47]  INFO [localhost] Scanning OS pkg in fast mode
[Dec 14 09:07:47]  INFO [localhost] Scanning listen port...
[Dec 14 09:07:47]  INFO [localhost] Using Port Scanner: Vuls built-in Scanner


Scan Summary
================
localhost       ubuntu18.04     539 installed


To view the detail, vuls tui is useful.
To send a report, run vuls report -h.

Vuls کارهایی که در این فرآیند انجام داده را ثبت کرده است. برای مشاهده گزارشی از آسیب پذیری هایی که شناسایی کرده است، اجرا کنید:

vuls tui

Vuls نمای گزارش را به چهار پانل تقسیم می کند:

  • ماشین‌های اسکن شده: در سمت چپ بالا، ماشین‌هایی را که Vuls اسکن کرده‌اند فهرست می‌کند.
  • آسیب‌پذیری‌های یافت شده: در سمت راست لیست ماشین قرار دارد، آسیب‌پذیری‌های Vuls موجود در بسته‌های نصب شده را نشان می‌دهد.
  • اطلاعات دقیق: قسمت سمت چپ صفحه را اشغال می کند، اطلاعات دقیق در مورد آسیب پذیری را نشان می دهد که از پایگاه های داده استخراج شده است.
  • بسته های تحت تأثیر: در سمت راست اطلاعات دقیق قرار دارد، نشان می دهد که نسخه های بسته تحت تأثیر کدامند و آیا نسخه ثابت وجود دارد.

می توانید با فشار دادن ENTER مکان نما را در پانل ها بچرخانید و با فلش های صفحه کلید حرکت کنید. وقتی کارتان تمام شد، CTRL+C را برای خروج فشار دهید.

در این مرحله، یک اسکن محلی را اجرا کرده و نتایج را بررسی کردید. در بخش بعدی (اختیاری)، Vuls را برای اسکن چندین ماشین هدف پیکربندی خواهید کرد.

مرحله 7 – (اختیاری) پیکربندی ماشین‌های هدف چندگانه

در این بخش، Vuls را برای اسکن چندین ماشین هدف پیکربندی می‌کنید. این مستلزم پیکربندی /etc/sudoers روی هدف و پیکربندی Vuls برای اسکن هدف است.

در مرحله قبل، Vuls را برای اسکن ماشین محلی (localhost) پیکربندی کردید. شما می توانید هر تعداد سرور که می خواهید اضافه کنید، به شرطی که موارد زیر را داشته باشید:

  • IP سرور مورد نظر
  • دسترسی ریشه به سرور مورد نظر
  • یک حساب کاربری موجود در سرور مورد نظر

شما فقط می توانید از یک حساب کاربری غیر ریشه در سرور مورد نظر برای اسکن در حالت سریع استفاده کنید. برای فعال کردن اسکن در حالت‌های روت سریع و عمیق، باید فایل /etc/sudoers را در ماشین(های) مورد نظر ویرایش کنید. فایل sudoers کنترل می کند که کاربران می توانند چه دستوراتی را اجرا کنند و همچنین اینکه آیا برای دستورات مشخص شده به رمز عبور نیاز دارید یا خیر.

از آنجایی که visudo ابزاری برای تعریف قوانین برای دسترسی و دسترسی ممتاز است، شما فقط می توانید آن را به صورت root اجرا کنید. به دلیل اهمیت sudoers، فایل بدون دادن اخطار با خطا خارج نمی شود.

در سرور هدف، به عنوان root وارد شوید و با اجرای visudo، sudoers را برای ویرایش باز کنید:

visudo

این خط را به انتهای فایل اضافه کنید:

/etc/sudoers

sammy-shark ALL=(ALL) NOPASSWD: /usr/bin/apt-get update, /usr/bin/stat *, /usr/sbin/checkrestart

این خط به sudo دستور می دهد تا به کاربر sammy-shark اجازه دهد تا آپدیت apt-get، checkrestart و هر دستوری که از stat در دسترس است را بدون ارائه رمز عبور اجرا کند.

ذخیره کنید و فایل را ببندید. اگر در فرآیند یک خطای نحوی مرتکب شدید، visudo به شما اطلاع می‌دهد و پیشنهاد می‌کند دوباره آن را ویرایش کنید یا خارج شوید.

Vuls از ابزار checkrestart برای بررسی بسته هایی که به روز شده اند، اما نیاز به راه اندازی مجدد دارند، استفاده می کند. برای اطمینان از اینکه سرور هدف آن را دارد، با اجرای دستور زیر آن را نصب کنید:

apt install debian-goodies -y

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

برای افزودن یک سرور جدید برای اسکن، config.toml را باز کنید و خطوط زیر را زیر علامت [سرورها] اضافه کنید:

/usr/share/vuls-data/config.toml

[servers.target_name]
host = "target_ip"
port = "22"
user = "account_username"
keyPath = "/home/sammy/.ssh/id_rsa"
scanMode = [ "deep" ] # "fast", "fast-root" or "deep"

خطوط بالا به عنوان الگویی برای افزودن سرورهای جدید عمل می کنند. به یاد داشته باشید که target_name را با نام دلخواه، target_ip را با IP سرور مورد نظر، account_username را با نام کاربری جایگزین کنید و مسیر کلید RSA خصوصی خود را ارائه دهید. Vuls از احراز هویت رمز عبور SSH پشتیبانی نمی کند، بنابراین تعیین یک مسیر کلیدی ضروری است.

ذخیره کنید و فایل را ببندید.

در مرحله بعد، برای هر سرور هدفی که اضافه کرده اید، کلیدهای RSA را در دستگاه محلی تأیید خواهید کرد. برای رسیدن به این هدف، از اولین سرور خود با کلید مناسب وارد سرور مورد نظر می شوید، مانند:

ssh sammy-shark@target_ip -i /home/sammy/.ssh/id_rsa

به یاد داشته باشید که مسیر کلید RSA خصوصی خود را وارد کنید. وقتی از شما پرسیده شد که آیا می خواهید به اتصال ادامه دهید، بله را وارد کنید، سپس با فشار دادن CTRL + D از سیستم خارج شوید.

اگر در مورد باز بودن مجوزهای کلیدی با خطا مواجه شدید، با اجرای دستور زیر آنها را روی 600 تنظیم کنید:

chmod 600 account_rsa_key

تنظیم مجوزها روی 600 تضمین می کند که فقط مالک می تواند فایل کلید را بخواند و بنویسد.

برای بررسی اعتبار پیکربندی جدید، دستور زیر را اجرا کنید:

vuls configtest

خروجی جزئیات همه چیزهایی را که Vuls بررسی کرده است، مانند وابستگی‌ها، دسترسی ابرکاربر و نسخه‌های سیستم‌عامل نشان می‌دهد. اگر خطایی وجود دارد، config.toml خود را با تنظیمات موجود در آموزش بررسی کنید.

در این مرحله، سرورهای هدف بیشتری را به پیکربندی Vuls خود اضافه کردید، بنابراین آنها را برای اسکن علامت گذاری کردید. در بخش بعدی، Vuls را برای اسکن دوره ای و ارسال گزارش ها به یک فضای کاری پیکربندی شده Slack پیکربندی می کنید.

مرحله 8 – پیکربندی اسکن دوره ای و گزارش به Slack

در این بخش، Vuls را پیکربندی می‌کنید تا گزارش‌ها را به Slack ارسال کند و یک cron job برای اجرای دوره‌ای اسکن Vuls ایجاد کنید.

برای استفاده از ادغام Slack، باید یک وب هوک ورودی در Slack برای فضای کاری خود داشته باشید. وب هوک های ورودی یک راه ساده برای یک برنامه کاربردی برای ارائه اطلاعات بلادرنگ از سایر برنامه ها است. در این مورد، Vuls را برای گزارش به کانال Slack خود پیکربندی می‌کنید.

اگر تا به حال یک هوک ایجاد نکرده اید، ابتدا باید یک برنامه برای فضای کاری خود ایجاد کنید. برای انجام این کار ابتدا وارد Slack شده و به صفحه ایجاد اپلیکیشن بروید. نامی را که می‌شناسید انتخاب کنید، فضای کاری مورد نظر را انتخاب کنید و روی ایجاد برنامه کلیک کنید.

به صفحه تنظیمات برنامه جدید هدایت خواهید شد. روی Incoming Webhooks در نوار ناوبری سمت چپ کلیک کنید.

با چرخاندن دکمه سوئیچ در کنار عنوان فعال سازی وب هوک های ورودی، وب هوک ها را فعال کنید.

بخش جدیدی در پایین صفحه باز خواهد شد. به پایین بروید و روی دکمه Add New Webhook to Workspace کلیک کنید. در صفحه بعد کانالی که می خواهید گزارش ها به آن ارسال شود را انتخاب کنید و روی Allow کلیک کنید.

به صفحه تنظیمات مربوط به وب هوک ها هدایت می شوید و یک وب هوک جدید را در جدول می بینید. روی Copy کلیک کنید تا آن را در کلیپ بورد کپی کنید و برای استفاده بعدی یادداشت کنید.

سپس، config.toml را برای ویرایش باز کنید:

sudo nano config.toml

خطوط زیر را اضافه کنید:

/usr/share/vuls-data/config.toml

[slack]
hookURL      = "your_hook_url"
channel      = "#your_channel_name"
authUser     = "your_username"
#notifyUsers  = ["@username"]

your_hook_URL را با URL webhook که قبلاً ذکر کردید، your_channel_name را با نام کانال مورد نظر، و your_username را با نام کاربری که وب‌هوک را ایجاد کرده است، جایگزین کنید. ذخیره کنید و فایل را ببندید.

برای آزمایش ادغام، می‌توانید با اجرای گزارش vuls گزارشی مانند زیر ایجاد کنید:

sudo vuls report -to-slack

Vuls چند لحظه طول می کشد تا اجرا شود و با موفقیت از آن خارج شود. اگر خطایی نشان داد، آنچه را که وارد کرده‌اید در خطوط قبل بررسی کنید.

می توانید برنامه Slack را بررسی کنید و تأیید کنید که Vuls با موفقیت گزارش را ارسال کرده است.

اکنون که گزارش‌دهی را پیکربندی کرده‌اید، اسکن‌های زمان‌بندی شده را تنظیم می‌کنید. cron یک زمانبندی کار مبتنی بر زمان است که در هر ماشین اوبونتو یافت می شود. از طریق فایل crontab پیکربندی می‌شود که دستوری را با نحو دقیق مشخص می‌کند که چه زمانی باید اجرا شود. برای کمک به سهولت در ویرایش، از ابزار crontab استفاده خواهید کرد که فایل crontab فعلی را در یک ویرایشگر باز می کند.

فایل crontab فعلی را با اجرای دستور زیر باز کنید:

crontab -e

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

خط زیر را به انتهای فایل اضافه کنید:

0 0 * * * vuls scan -config=/usr/share/vuls-data/config.toml; vuls report -config=/usr/share/vuls-data/config.toml > /dev/null 2>&1

خط بالا به cron دستور می دهد که اسکن vuls و گزارش vuls را با پیکربندی داده شده هر روز در ظهر اجرا کند (در نحو cron با 0 0 * * * مشخص می شود).

ذخیره کنید و فایل را ببندید.

در این مرحله، Vuls را به فضای کاری Slack خود متصل کرده‌اید و cron را برای اجرای اسکن Vuls و گزارش هر روز در ظهر پیکربندی کرده‌اید.

نتیجه

شما اکنون با موفقیت Vuls را با اسکن و گزارش خودکار روی سرور اوبونتو 18.04 راه اندازی کرده اید.

با Vuls، ارزیابی آسیب‌پذیری به فرآیند یکپارچه‌تر در محیط‌های تولید تبدیل می‌شود. به‌عنوان جایگزینی برای راه‌اندازی cron، می‌توان از Vuls در یک گردش کار استقرار مداوم استفاده کرد، زیرا اسکن‌های آن سبک هستند و می‌توانید در صورت نیاز آن‌ها را اجرا کنید. همچنین می توانید برای محدود کردن دسترسی و کاهش نیاز به دسترسی ریشه، یک فایروال با Vuls پیاده سازی کنید.

 

https://vpsgol.net/product/vps-germany/

 

https://vpsgol.net/product/vps-usa/

 

https://vpsgol.net/product/vps-france/

 

https://vpsgol.net/product/vps-canada/

 

https://vpsgol.net/product/vps-poland/

 

https://vpsgol.net/product/vps-netherlands/

 

https://vpsgol.net/product/vps-england/

برچسب‌ها:VPS یا سرور مجازیVulsاوبونتو 18.04خرید سرور مجازیراهنمای سرور مجازیسرور اوبونتو 18.04سرور مجازی آمریکافایروال با Vulsنحوه استفاده از Vuls

  • behnam gol mohamadi
  • ۰
  • ۰

چگونه یک ماژول سفارشی Terraform بسازیم

ورود به سایت

معرفی

ماژول های Terraform به شما امکان می دهد منابع متمایز زیرساخت خود را در یک منبع واحد و یکپارچه گروه بندی کنید. می توانید بعداً با سفارشی سازی های احتمالی ، بدون تکرار تعاریف منابع در هر زمان که به آنها نیاز دارید ، مجدداً از آنها استفاده کنید ، که برای پروژه های بزرگ با ساختارهای پیچیده مفید است. می توانید نمونه های ماژول را با استفاده از متغیرهای ورودی که تعریف کرده اید و همچنین با استفاده از خروجی ها اطلاعات را از آنها استخراج کنید. علاوه بر ایجاد ماژول های سفارشی خود ، می توانید از ماژول های از پیش ساخته شده که به طور عمومی در رجیستری Terraform منتشر شده اند نیز استفاده کنید. توسعه دهندگان می توانند با استفاده از ورودی هایی مانند ماژول هایی که ایجاد می کنید از آنها استفاده کرده و آنها را سفارشی کنند ، اما کد منبع آنها در ابر ذخیره شده و از ابر خارج می شود.

در این آموزش ، ماژول Terraform را ایجاد می کنید که چندین قطره را در پشت Load Balancer برای افزونگی راه اندازی می کند. شما همچنین از ویژگی های for_each و count حلقه زبان پیکربندی Hashicorp (HCL) برای استقرار چندین نمونه سفارشی ماژول به طور همزمان استفاده خواهید کرد.

ساختار و مزایای ماژول

در این بخش ، یاد می گیرید که ماژول ها چه مزایایی را به همراه دارند ، معمولاً کجا در پروژه قرار می گیرند و چگونه باید ساختار یابند.

ماژول های سفارشی Terraform برای محصور کردن اجزای متصل شده که اغلب در پروژه های بزرگتر مورد استفاده قرار می گیرند ، ایجاد می شوند. آنها مستقل هستند و فقط منابع ، متغیرها و ارائه دهندگان مورد نیاز خود را جمع می کنند.

ماژول ها معمولاً در یک پوشه مرکزی در ریشه پروژه ، هر کدام در زیر پوشه مربوطه در زیر ذخیره می شوند. به منظور حفظ یک جداسازی تمیز بین ماژول ها ، همیشه آنها را به گونه ای طراحی کنید که دارای یک هدف واحد باشند و اطمینان حاصل کنید که هرگز شامل زیرمجموعه ها نیستند.

وقتی می بینید که ماژول ها را با استفاده از سفارشی سازی های نادر تکرار می کنید ، از طرح های منابع خود ایجاد کنید مفید است. بسته بندی یک منبع واحد به عنوان یک ماژول می تواند اضافی باشد و به تدریج سادگی معماری کلی را حذف می کند.

برای پروژه های کوچک توسعه ای و آزمایشی ، استفاده از ماژول ها ضروری نیست زیرا در این موارد پیشرفت چندانی ندارند. ماژول ها با قابلیت سفارشی سازی خود ، عنصر اصلی پروژه های پیچیده ساختار یافته هستند. توسعه دهندگان به دلیل مزایای قابل توجه در جلوگیری از تکرار کد ، از ماژول ها برای پروژه های بزرگتر استفاده می کنند. ماژول ها همچنین مزیتی را ارائه می دهند که تعاریف فقط نیاز به اصلاح در یک مکان دارند ، که سپس در بقیه زیرساخت ها منتشر می شود.

سپس ماژول ها را در پروژه های Terraform خود تعریف ، استفاده و سفارشی کنید.

ایجاد یک ماژول

در این بخش ، شما چند قطره و Load Balancer را به عنوان منابع Terraform تعریف کرده و آنها را در یک ماژول قرار می دهید. شما همچنین می توانید ماژول حاصل را با استفاده از ورودی های ماژول سفارشی کنید.

ماژول را در دایرکتوری به نام droplet-lb ، در زیر دایرکتوری به نام modules ذخیره می کنید. با فرض اینکه در فهرست راهنمای terraform-modules که به عنوان بخشی از پیش نیازها ایجاد کرده اید هستید ، هر دو را همزمان اجرا کنید:

mkdir -p modules/droplet-lb

آرگومان -p به mkdir دستور می دهد تا همه دایرکتوری ها را در مسیر ارائه شده ایجاد کند.

به آن بروید:

cd modules/droplet-lb

همانطور که در قسمت قبل اشاره شد ، ماژول ها شامل منابع و متغیرهایی هستند که از آنها استفاده می کنند. با شروع از Terraform 0.13 ، آنها همچنین باید تعاریفی از ارائه دهندگان مورد استفاده خود داشته باشند. ماژول ها نیازی به پیکربندی خاصی ندارند تا توجه داشته باشید که کد نشان دهنده یک ماژول است ، زیرا Terraform هر فهرست شامل کد HCL را به عنوان یک ماژول ، حتی فهرست اصلی پروژه ، در نظر می گیرد.

متغیرهای تعریف شده در یک ماژول به عنوان ورودی های آن نشان داده می شوند و می توانند در تعاریف منابع برای سفارشی سازی آنها استفاده شوند. ماژولی که ایجاد می کنید دارای دو ورودی است: تعداد Droplets برای ایجاد و نام گروه آنها. ایجاد و باز کردن برای ویرایش فایلی به نام variables.tf که در آن متغیرها را ذخیره می کنید:

nano variables.tf

خطوط زیر را اضافه کنید:

modules/droplet-lb/variables.tf

variable "droplet_count" {}
variable "group_name" {}

ذخیره کنید و فایل را ببندید.

شما تعریف Droplet را در فایلی با نام droplets.tf ذخیره خواهید کرد. ایجاد و باز کردن آن برای ویرایش:

nano droplets.tf

خطوط زیر را اضافه کنید:

modules/droplet-lb/droplets.tf

resource "vpsgol_droplet" "droplets" {
  count  = var.droplet_count
  image  = "ubuntu-20-04-x64"
  name   = "${var.group_name}-${count.index}"
  region = "fra1"
  size   = "s-1vcpu-1gb"
}

برای پارامتر count که مشخص می کند چند نمونه از منبع را ایجاد کنید ، از متغیر droplet_count استفاده می کنید. مقدار آن زمانی مشخص می شود که ماژول از کد اصلی پروژه فراخوانی شود. نام هر یک از Droplets های مستقر متفاوت خواهد بود ، که با افزودن فهرست قطره فعلی به نام گروه ارائه شده ، به آن می رسید. استقرار Droplets در منطقه fra1 خواهد بود و اوبونتو 20.04 را اجرا خواهند کرد.

پس از اتمام کار ، فایل را ذخیره و ببندید.

با Droplets که اکنون تعریف شده است ، می توانید به ایجاد Load Balancer بروید. شما تعریف منابع آن را در فایلی با نام lb.tf ذخیره خواهید کرد. با اجرای آن ، آن را برای ویرایش ایجاد کرده و باز کنید:

nano lb.tf

تعریف منابع آن را اضافه کنید:

modules/droplet-lb/lb.tf

resource "vpsgol_loadbalancer" "www-lb" {
  name   = "lb-${var.group_name}"
  region = "fra1"

  forwarding_rule {
    entry_port     = 80
    entry_protocol = "http"

    target_port     = 80
    target_protocol = "http"
  }

  healthcheck {
    port     = 22
    protocol = "tcp"
  }

  droplet_ids = [
    for droplet in vpsgol_droplet.droplets:
      droplet.id
  ]
}

شما Load Balancer را با نام گروه در نام آن تعریف می کنید تا قابل تشخیص باشد. شما آن را به همراه Droplets در منطقه fra1 مستقر می کنید. دو بخش بعدی پورت ها و پروتکل های هدف و نظارت را مشخص می کند.

بلوک droplet_ids برجسته ، شناسه Droplets را که باید توسط Load Balancer مدیریت شود ، می گیرد. از آنجا که چند قطره وجود دارد ، و تعداد آنها از قبل مشخص نیست ، شما از حلقه for برای عبور از مجموعه Droplets (vpsgol_droplet.droplets) و گرفتن شناسه آنها استفاده می کنید. شما حلقه for را با پرانتز ([]) احاطه می کنید تا مجموعه حاصل یک لیست باشد.

اکنون Droplet ، Load Balancer و متغیرها را برای ماژول خود تعریف کرده اید. شما باید الزامات ارائه دهنده را مشخص کنید ، مشخص کنید که ماژول از کدام ارائه دهندگان استفاده می کند ، از جمله نسخه آنها و جایی که آنها واقع شده اند. از آنجا که Terraform 0.13 است ، ماژول ها باید به صراحت منابع ارائه دهندگان غیر Hashicorp مورد استفاده خود را مشخص کنند. این به این دلیل است که آنها آنها را از پروژه اصلی به ارث نمی برند.

الزامات ارائه دهنده را در فایلی با نام provider.tf ذخیره خواهید کرد. با اجرای آن آن را برای ویرایش ایجاد کنید:

nano provider.tf

ماژول ها همچنین از خروجی ها پشتیبانی می کنند که می توانید از آنها برای استخراج اطلاعات داخلی در مورد وضعیت منابع خود استفاده کنید. شما یک خروجی تعریف می کنید که آدرس IP Load Balancer را نشان می دهد و آن را در فایلی با نام outputs.tf ذخیره می کنید. آن را برای ویرایش ایجاد کنید:

nano outputs.tf

تعریف زیر را اضافه کنید:

modules/droplet-lb/outputs.tf

output "lb_ip" {
  value = vpsgol_loadbalancer.www-lb.ip
}

این خروجی آدرس IP Load Balancer را بازیابی می کند. ذخیره کنید و فایل را ببندید.

ماژول droplet-lb از لحاظ عملکردی کامل است و آماده استقرار است. شما آن را از کد اصلی ، که در ریشه پروژه ذخیره می کنید ، صدا می زنید. ابتدا ، با دوبار بالا رفتن از فهرست پرونده خود به آن بروید:

cd ../..

سپس ، برای ویرایش فایلی به نام main.tf ایجاد و باز کنید ، که در آن از ماژول استفاده می کنید:

nano main.tf

خطوط زیر را اضافه کنید:

main.tf

module "groups" {
  source = "./modules/droplet-lb"

  droplet_count = 3
  group_name    = "group1"
}

output "loadbalancer-ip" {
  value = module.groups.lb_ip
}

در این اعلان ماژول droplet-lb را که در فهرست راهنمای تعیین شده به عنوان منبع قرار دارد فرا می خوانید. شما ورودی ارائه شده ، droplet_count و group_name را که روی group1 تنظیم شده است پیکربندی می کنید تا بعداً بتوانید بین نمونه ها تشخیص دهید.

از آنجا که خروجی IP Load Balancer در یک ماژول تعریف شده است ، هنگام اعمال پروژه به طور خودکار نشان داده نمی شود. راه حل این مسئله ایجاد خروجی دیگری است که مقدار آن را بازیابی می کند (loadbalancer_ip). پس از اتمام کار فایل را ذخیره و ببندید.

با راه اندازی اولیه ماژول را راه اندازی کنید:

terraform init

خروجی به صورت زیر خواهد بود:

 

Output

Initializing modules...
- groups in modules/droplet-lb

Initializing the backend...

Initializing provider plugins...
- Reusing previous version of vpsgol/vpsgol from the dependency lock file
- Using previously-installed vpsgol/vpsgol v2.10.1

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

می توانید برنامه ریزی پروژه را امتحان کنید تا ببینید Terraform با اجرای چه اقداماتی انجام می دهد:

terraform plan -var “do_token=${DO_PAT}”

خروجی مشابه این خواهد بود:

 

Output

...
Terraform used the selected providers to generate the following execution plan. Resource actions are
indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # module.groups.vpsgol_droplet.droplets[0] will be created
  + resource "vpsgol_droplet" "droplets" {
...
      + name                 = "group1-0"
...
    }

  # module.groups.vpsgol_droplet.droplets[1] will be created
  + resource "vpsgol_droplet" "droplets" {
...
      + name                 = "group1-1"
...
    }

  # module.groups.vpsgol_droplet.droplets[2] will be created
  + resource "vpsgol_droplet" "droplets" {
...
      + name                 = "group1-2"
...
    }

  # module.groups.vpsgol_loadbalancer.www-lb will be created
  + resource "vpsgol_loadbalancer" "www-lb" {
...
      + name                     = "lb-group1"
...
    }

Plan: 4 to add, 0 to change, 0 to destroy.
...

این خروجی نشان می دهد که Terraform سه قطره ایجاد می کند ، به نام های group1-0 ، group1-1 و group1-2 ، و همچنین یک Load Balancer به نام group1-lb ایجاد می کند ، که ترافیک به سه قطره را از و خارج مدیریت می کند.

با اجرای پروژه می توانید پروژه را روی ابر اعمال کنید:

terraform apply -var “do_token=${DO_PAT}”

در صورت درخواست بله را وارد کنید. خروجی تمام اقدامات را نشان می دهد و آدرس IP Load Balancer نیز نشان داده می شود:

 

Output

module.groups.vpsgol_droplet.droplets[1]: Creating...
module.groups.vpsgol_droplet.droplets[0]: Creating...
module.groups.vpsgol_droplet.droplets[2]: Creating...
...
Apply complete! Resources: 4 added, 0 changed, 0 destroyed.

Outputs:

loadbalancer-ip = ip_address

از آنجا که در مرحله بعد پیکربندی را به طور قابل توجهی تغییر می دهید ، منابع اجرا شده را با اجرای زیر از بین ببرید:

terraform destroy -var “do_token=${DO_PAT}”

در صورت درخواست بله را وارد کنید. خروجی به این صورت خاتمه می یابد:

 

Output

...
Destroy complete! Resources: 4 destroyed.

در این مرحله ، ماژولی ایجاد کرده اید که شامل تعدادی Droplets و Load Balancer است که به طور خودکار برای مدیریت ترافیک ورودی و خروجی آنها پیکربندی می شود. اکنون می توانید چندین نمونه از یک ماژول را از یک کد با استفاده از for_each و count استفاده کنید.

استقرار موارد متعدد ماژول

در این بخش ، از count و for_each برای استقرار چندین بار ماژول droplet-lb ، با سفارشی سازی استفاده خواهید کرد.

با استفاده از شمارش

یک راه برای استقرار چند نمونه از یک ماژول به طور همزمان این است که تعداد آنها را به پارامتر count منتقل کنید ، که به طور خودکار برای هر ماژول در دسترس است. main.tf را برای ویرایش باز کنید:

nano main.tf

با حذف تعریف خروجی موجود ، آن را به شکل زیر تغییر دهید:

main.tf

module "groups" {
  source = "./modules/droplet-lb"

  count  = 3

  droplet_count = 3
  group_name    = "group1-${count.index}"
}

با تنظیم شمارش روی 3 ، به Terraform دستور می دهید که ماژول را سه بار ، هر کدام با نام گروهی متفاوت ، مستقر کند. پس از اتمام کار ، فایل را ذخیره و ببندید.

برنامه ریزی استقرار با اجرای:

terraform plan -var “do_token=${DO_PAT}”

خروجی طولانی خواهد بود و به شکل زیر خواهد بود:

 

Output

...
Terraform used the selected providers to generate the following execution plan. Resource actions are
indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # module.groups[0].vpsgol_droplet.droplets[0] will be created
...
  # module.groups[0].vpsgol_droplet.droplets[1] will be created
...
  # module.groups[0].vpsgol_droplet.droplets[2] will be created
...
  # module.groups[0].vpsgol_loadbalancer.www-lb will be created
...
  # module.groups[1].vpsgol_droplet.droplets[0] will be created
...
  # module.groups[1].vpsgol_droplet.droplets[1] will be created
...
  # module.groups[1].vpsgol_droplet.droplets[2] will be created
...
  # module.groups[1].vpsgol_loadbalancer.www-lb will be created
...
  # module.groups[2].vpsgol_droplet.droplets[0] will be created
...
  # module.groups[2].vpsgol_droplet.droplets[1] will be created
...
  # module.groups[2].vpsgol_droplet.droplets[2] will be created
...
  # module.groups[2].vpsgol_loadbalancer.www-lb will be created
...

Plan: 12 to add, 0 to change, 0 to destroy.
...

Terraform در خروجی توضیح می دهد که هر یک از سه نمونه ماژول دارای سه Droplet و Load Balancer مربوط به آنها خواهد بود.

استفاده از for_each

هنگامی که به سفارشی سازی پیچیده تر نیاز دارید ، یا زمانی که تعداد موارد به داده های شخص ثالث (اغلب به صورت نقشه ارائه می شود) که هنگام نوشتن کد مشخص نیست ، می توانید از for_each برای ماژول ها استفاده کنید.

اکنون نقشه ای را تعریف می کنید که نام گروه ها را با تعداد Droplet جفت می کند و موارد قطره ای-lb را مطابق آن مستقر می کند. main.tf را برای ویرایش با اجرا باز کنید:

nano main.tf

فایل را اصلاح کنید تا به این شکل درآید:

main.tf

variable "group_counts" {
  type    = map
  default = {
    "group1" = 1
    "group2" = 3
  }
}

module "groups" {
  source   = "./modules/droplet-lb"
  for_each = var.group_counts

  droplet_count = each.value
  group_name    = each.key
}

شما ابتدا نقشه ای به نام group_counts تعریف می کنید که حاوی چند قطره است که یک گروه معین باید داشته باشد. سپس ، ماژول droplet-lb را فرا می خوانید ، اما مشخص می کنید که حلقه for_each باید در var.group_counts ، نقشه ای که قبلاً تعریف کرده اید ، عمل کند. droplet_count each.value ، مقدار جفت فعلی ، که تعداد Droplets برای گروه فعلی است را می گیرد. group_name نام گروه را دریافت می کند.

پس از اتمام کار فایل را ذخیره و ببندید.

سعی کنید پیکربندی را با اجرای زیر اعمال کنید:

terraform plan -var “do_token=${DO_PAT}”

در خروجی اقدامات Terraform برای ایجاد دو گروه با Droplets و Load Balancers خود شرح داده می شود:

 

Output

...
Terraform used the selected providers to generate the following execution plan. Resource actions are
indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # module.groups["group1"].vpsgol_droplet.droplets[0] will be created
...
  # module.groups["group1"].vpsgol_loadbalancer.www-lb will be created
...
  # module.groups["group2"].vpsgol_droplet.droplets[0] will be created
...
  # module.groups["group2"].vpsgol_droplet.droplets[1] will be created
...
  # module.groups["group2"].vpsgol_droplet.droplets[2] will be created
...
  # module.groups["group2"].vpsgol_loadbalancer.www-lb will be created
...

در این مرحله ، شما از count و for_each برای استقرار چندین نمونه سفارشی از یک ماژول از یک کد استفاده کرده اید.

نتیجه

در این آموزش ، ماژول های Terraform را ایجاد و به کار گرفته اید. شما از ماژول ها برای گروه بندی منابع مرتبط منطقی با هم استفاده کردید و آنها را به منظور استقرار چندین نمونه مختلف از یک تعریف کد مرکزی سفارشی کردید. شما همچنین از خروجی ها برای نشان دادن ویژگی های منابع موجود در ماژول استفاده کردید.

 

برچسب‌ها:

  • behnam gol mohamadi