تاکنون اینونتوریها(Inventories) و ماژولهای مرسوم(Common Modules) انسیبل را آموختیم. اکنون باید به مباحث پیشرفته تری از «انسیبل» بپردازیم.
در قسمت صفرم اشاره کردیم که انسیبل یک فریمورک قدرتمند برای اوتوماسیون ماشینهای یونیکسی و ویندوزی است. انسیبل با بهره گیری از از مفهومی به اسم پلیبوک(Playbook) و همچنین قابلیت ماژولار خود و البته از انعطاف زبان پایتون و yaml هم بهره میبرد تا مطابق با دستور العمل خاصی سلسله وظایف مشخصی را بر روی یک تا n هاست انجام دهد. در این قسمت ما بصورت جداگانه به زبان Yaml خواهیم پرداخت.
YAML – YAML Ain’t Markup Language
از آنجایی که «انسیبل» با زبان «پایتون» نوشته شده است میتوانیم از پایتون استفاده کنیم برای اینکه با مفاهیم YAML آشنا بشویم. البته ابزارهای دیگری هم برای تایید سینتکس yaml شما موجود هستند اما ما از روش پایتونیک و ساده تری بهره میبریم.
function yamlpy() { python -c 'import sys,yaml,pprint;pprint.pprint(yaml.load(open(sys.argv[1]).read(), Loader=yaml.FullLoader))' $1 }
وقتی که دستور بالا را کپی کنید و در ترمینال خود اجرا کنید میتوانید از دستور yamlpy
استفاده کنید و مسیر فایل yaml خود را بصورت آرگومان به دستور بدهید تا در خروجی ساختار فایل را بصورت آبجکتهای پایتونی به شما نمایش دهد. با این روش میخواهیم ببینیم که انسیبل چه نوع دیتا و دیتاهایی را پردازش خواهد کرد.
-
ساختار YAML فایلها
مهم ترین نکته در مورد YAML فایلها ابتدایی ترین نقطه آن است. هر yaml فایل با سه خط منهی ” ---
” در خط اول شروع میشود و با سه نقطه ” ...
” در خط آخر به اتمام میرسد. کامنت کردن در YAML هم با کارکتر #
امکان پذیر است.
$ cat revisions/01_03_yaml/01/test.yml --- # Every YAML file should end with three dots ...
اما اگر این فایل را با دستور yamlpy
مورد بررسی قرار دهیم خواهیم دید که از منظر انسیبل(در واقع زبان پایتون) مقدرا None
بازگردانده خواهد شد.
$ yamlpy revisions/01_03_yaml/01/test.yml None
در بازبینی دوم فایل YAML حاوی دو آیتم است:
$ cat revisions/01_03_yaml/02/test.yml --- key_1: first value key_2: second value # Every YAML file should end with three dots ...
این نوع از دیتا به Key/Value مشهور است. در این مثال کلید یک key_1
و کلید دو key_2
و مقادیر آنها first value
و second value
هستند. اگر این فایل را با دستور yamlpy اجرا کنیم خروجی به شکل دیکشنری خواهد بود. در ادامه به تفصل در مورد دیکشنری ها و لیستها صحبت خواهیم کرد.
$ yamlpy revisions/01_03_yaml/02/test.yml {'key_1': 'first value', 'key_2': 'second value'}
-
گیومه – “Double”, ‘Single’
در زبان YAML برای ایجاد یک متغیر String سه روش وجود دارد. بدون گیومه، با گیومه تگی و با گیومه دوتایی. در بازبینی سوم این سه روش قابل مشاهده است.
$ cat revisions/01_03_yaml/03/test.yml --- no_quotes: this is a string example double_quotes: "this is a string example" single_quotes: 'this is a string example' # Every YAML file should end with three dots ...
برای مشاهده آنها از منظر پایتون از ابزار yamlpy
استفاده میکنیم:
yamlpy revisions/01_03_yaml/03/test.yml
$ yamlpy revisions/01_03_yaml/03/test.yml {'double_quotes': 'this is a string example', 'no_quotes': 'this is a string example', 'single_quotes': 'this is a string example'}
همانگونه که مشاهده میکنید مقادیر هر کلید با یک Single Quote مشخص شده است.
در بازبینی چهارم تغییر کوچی ایجاد کردهایم. در انتهای هر خط یک کارکتر خاص به سر خط /n
اضافه کردیم. این کارکتر خاص شامل یک کارکتر اسکیپ یعنی /
و یک کارکتر خط جدید (سر خط) یعنی n
.
$ cat revisions/01_03_yaml/04/test.yml --- no_quotes: this is a string examplen double_quotes: "this is a string examplen" single_quotes: 'this is a string examplen' # Every YAML file should end with three dots ...
اما نکته مهم اینجاست که این کارکتر اسکیپ در مدل بدون گیومه و تک گیومه به عنوان یک کارکتر اسکیپ کد تفسیر نخواهد شد. به خروجی زیر توجه کنید:
$ yamlpy revisions/01_03_yaml/04/test.yml {'double_quotes': 'this is a string examplen', 'no_quotes': 'this is a string examplen', 'single_quotes': 'this is a string examplen'}
به همین دلیل توصیه میشود زمانی که نیاز به استفاده از کارکتر اسکیپ دارید از “Double Quote” استفاده کنید.
-
متغیرهای چند خطی – Multiline variable
اما هم اکنون که در مورد Strings صحبت میکنم شاید بد نباشد اگر به Multilines Strings هم اشاره کنیم. در بازبینی پنجم از کارکتر پایپ |
استفاده شده است اما رشته در چنید خط در پی هم نوشته شده است:
$ cat revisions/01_03_yaml/05/test.yml --- key_1: | this is a string that goes over multiple lines # Every YAML file should end with three dots ...
اما اگر از ابزار yamlpy برای بررسی فایل استفاده کنیم تمام رشته را در یک خط خواهیم داشت در حالی که هر خط با کارکتر خاص n
از هم جدا شده است.
$ yamlpy revisions/01_03_yaml/05/test.yml {'key_1': 'this is a stringnthat goes overnmultiple linesn'}
در بازبینی ششم اما بجای کارکتر پایپ از کارکتر بزرگتر >
استفاده کرده ایم:
$ cat revisions/01_03_yaml/06/test.yml --- example_key_1: > this is a string that goes over multiple lines # Every YAML file should end with three dots ...
همانگونه که در پایین ملاحظه میکنید تفاوت بزرگ کارکتر پایپ با کارکتر بزرگتر در اضافه کردن کارکتر خط جدید /n
به مقدار متغیر است:
yamlpy revisions/01_03_yaml/06/test.yml {'example_key_1': 'this is a string that goes over multiple linesn'}
در زمانهایی که مقدار متغیر ما از نوع رشته طولانی و دارای کلمات زیادی است، میتوانیم از این روش بهره ببریم تا کدهای yaml ما شکیلتر بشوند.
اما اگر دقت کنید در مثال بالا هم در انتهای رشته یک کارکتر /n
قابل رویت است. گاهی ما نیاز داریم که این کارکتر در انسیبل تفسیر نشود. به بازبینی هفتم بریم:
$ cat revisions/01_03_yaml/07/test.yml --- example_key_1: >- this is a string that goes over multiple lines # Every YAML file should end with three dots ...
در اینجا برای حذف /n
در انتها بعد از کارکتر بزرگتر از یک -
استفاده میکنیم. خروجی زیر را مشاهده کنید:
$ yamlpy revisions/01_03_yaml/07/test.yml {'example_key_1': 'this is a string that goes over multiple lines'}
اما برای تعریف کردن یک متغیر از نوع اینتجر به صورت خودکار تفسیر میشود. برای مثال در پوشه بازبینی هشتم فایل test.yml را مشاهده کنید:
cat revisions/01_03_yaml/08/test.yml --- example_integer: 1 # Every YAML file should end with three dots ...
و خروجی آن در دستور yamlpy که قبلا برای تایید فایلهای yaml خود تعریف کردهایم:
yamlpy revisions/01_03_yaml/08/test.yml {'example_integer': 1}
قبل از این هم اشاره کردیم که در تفسیر متغیرها در انسیبل همانند پایتون است(در واقع پایتون است که با استفاده از ماژول yaml فایلهای yaml و متغیرهای تعریف شده در آن را تفسیر میکند). بنابراین اگر نیاز باشد که عددی از نوع رشته به یک متغیر منسوب کنیم از گیومه استفاده خواهیم کرد:
cat revisions/01_03_yaml/09/test.yml --- example_integer: "1" # Every YAML file should end with three dots ...
و طبیعتا در خروجی دستور yamlpy این مقدار با گیومه مشخص شده است:
yamlpy revisions/01_03_yaml/09/test.yml {'example_integer': '1'}
-
بولین در انسیبل – True/False
در بازبینی دهم ما تقریبا همه روشهایی که میشود مقدار True
و یا False
را به یک متغیر منسوب کنیم را پوشش دادهایم:
cat revisions/01_03_yaml/10/test.yml --- # false, False, FALSE, no, No, NO, off, Off, OFF # true, True, TRUE, yes, Yes, YES, on, On, ON # n.b. n does not equal false, y does not equal true is_false_01: false is_false_02: False is_false_03: FALSE is_false_04: no is_false_05: No is_false_06: NO is_false_07: off is_false_08: Off is_false_09: OFF is_false_10: n is_true_01: true is_true_02: True is_true_03: TRUE is_true_04: yes is_true_05: Yes is_true_06: YES is_true_07: on is_true_08: On is_true_09: ON is_true_10: y # Every YAML file should end with three dots ...
نکته بسیار مهمی در خط هفتم این فایل بصورت کامنت مشخص شده است. در yaml برای تعریف کردن مقدار Ture
نمیشود از y
و همچنین برای تعریف کردن مقدار False
نمیشود از n
استفاده کرد. در این صورت پایتون آنها را به عنوان یک رشته که حاوی که یک کارکتر است تفسیر میکند. خروجی زیر بیانگر این ادعا است:
$ yamlpy revisions/01_03_yaml/10/test.yml {'is_false_01': False, 'is_false_02': False, 'is_false_03': False, 'is_false_04': False, 'is_false_05': False, 'is_false_06': False, 'is_false_07': False, 'is_false_08': False, 'is_false_09': False, 'is_false_10': 'n', 'is_true_01': True, 'is_true_02': True, 'is_true_03': True, 'is_true_04': True, 'is_true_05': True, 'is_true_06': True, 'is_true_07': True, 'is_true_08': True, 'is_true_09': True, 'is_true_10': 'y'}
همانگونه که میبنید کلید های is_false_10
و is_true_10
یک رشته را به عنوان مقدار خود در نظر گرفته. توصیه میشود برای عدم ابهام در کدهای انسیبل از مقدار True
و یا False
استفاده کنید.
- لیستها و دیکشنریها – Lists and Dictionaries
تا کنون ما در همه فایلهای yaml خود از دیتا نوع دیشکنری استفاده کردیم. طبیعتا برای تعریف یک دیشنری به یک کلید و مقدار آن نیاز بود در مثالها به کرار مورد استفاده قرار گرفته. اما در بازبینی یازدهم میبینم که تعیریف کردن متغیر از نوع لیسن به چه صورت است.
$ cat revisions/01_03_yaml/11/test.yml --- # Every YAML file should start with three dashes - item 1 - item 2 - item 3 - item 4 - item 5 # Every YAML file should end with three dots ...
در واقع برای تعریف کرد لیسن میتوان از کارکتر -
استفاده کرد و مقدار بعد از آن عنصر عضو آن لیست خواهد بود:
$ yamlpy revisions/01_03_yaml/11/test.yml ['item 1', 'item 2', 'item 3', 'item 4', 'item 5']
اما برای تعریف کردن دیکشنری نکته مهم استفاده از کارکتر :
بعد از کلید بود. به بازبینی دوازدهم دقت کنید:
$ cat revisions/01_03_yaml/12/test.yml --- example_key_1: example_value_1 example_key_2: example_value_2 # Every YAML file should end with three dots ...
و خروجی:
$ yamlpy revisions/01_03_yaml/12/test.yml {'example_key_1': 'example_value_1', 'example_key_2': 'example_value_2'}
اما نکته قابل تامل در انسیبل و استفاده از سینتکس yaml در بازبینی سیزدهم پوشش داده شده:
$ cat revisions/01_03_yaml/13/test.yml --- {example_key_1: example_value_1, example_key_2: example_value_2} # Every YAML file should end with three dots ...
همانگونه که مشاهده میکنید این امکان وجود دارد که از سینتکس زبان پایتون برای تعریف کردن متغیرهای از انواع مختلف استفاده کرد. در پایتون برای تعیرف کردن یک دیکشنری از کارترهای {}
استفاده میشود. خروجی بیانگر این ادعا است:
$ yamlpy revisions/01_03_yaml/13/test.yml {'example_key_1': 'example_value_1', 'example_key_2': 'example_value_2'}
دقیقا متغیرهای لیست هم از این قائده مستثنی نیستند. به بازبینی چهاردهم برویم:
$ cat revisions/01_03_yaml/14/test.yml --- [example_list_entry_1, example_list_entry_2] # Every YAML file should end with three dots ...
و خروجی:
$ yamlpy revisions/01_03_yaml/14/test.yml ['example_list_entry_1', 'example_list_entry_2']
-
فاصله گذاری – Indentation
اما زبان yaml هم مانند زبانهای مرسوم از قانون و قوانین خاص خود در خصوص فاصله گذاری تبعیت میکند. متغیرهای دیکشنری و لیست مثال خوبی برای توضیح این موضوع است. به بازبینی پانزدهم بریم:
$ cat revisions/01_03_yaml/15/test.yml --- example_key_1: example_value_1 - example_list_entry_1 # Every YAML file should end with three dots ...
در مثال بالا یک دیکشنری و یک لیست در یک سطح تعریف کردهایم. مسئله دقیقا اینجاست که از نظر yaml این نا معتبر است.
حتی اگر بصورت پایتونیک هم دو نوع متفاوت از دیتا را در یک سطح تعیرف کیند باز هم نا معتبر خواهد بود. بازبینی شانزدهم مثالی از این نمونه است:
$ cat revisions/01_03_yaml/16/test.yml --- {example_key_1: example_value_1} [example_list_entry_1] # Every YAML file should end with three dots ...
از آنجایی که زبان yaml برای نگه داری انوع دیتا طراحی شده است، در نظر میگرد که در هر سطح از میبایست یک نوع دیتا در نظر گرفته شود. برای سطح بندی میشود همانند پایتون از فاصله گذاری استفاده کرد. و این فاصله گذاری ( یا تورفتگی ) باید از یک الگوی مشترک در کل فایل تبعیت کنید. مرسوم است از دو کارکتر space
برای سطح بندی استفاده شود. شما میتوانید الگوی خود را داشته باشید، اما اگر قصد دارید کدهای خود را بصورت عمومی منتشر کنید توصیه میشود از همان دو کارکتر space
به ازای هر سطح استفاده کنید.
اما همانند پایتون این امکان وجود دارد یک دیتا از نوع لیست مقدار یک کلید دیکشنری باشد. برای نمونه به بازبینی هفدهم برویم:
$ cat revisions/01_03_yaml/17/test.yml --- example_key_1: - list item 1 - list item 2 example_key_2: - list item 3 - list item 4 # Every YAML file should end with three dots ...
در این مثال یک دیکشنری داریم که داری دو کلید است و هر کلید یک لیست به عنوان مقدار در خود دارد که هر کدام از این لیستها شامل دو عنصر است:
yamlpy revisions/01_03_yaml/17/test.yml {'example_key_1': ['list item 1', 'list item 2'], 'example_key_2': ['list item 3', 'list item 4']}
در بازبینی هجدهم مدل کمی پیچیده تر مثال زده شده است.
cat revisions/01_03_yaml/18/test.yml --- - example_1: - item_1 - item_2 - item_3 - example_2: - item_4 - item_5 - item_6 # Every YAML file should end with three dots ...
در این مثال یک لیست شامل دو عنصر که هر عنصر یک دیکشنری است و هر دیکشنری یک کلید دارد که مقدار آن برابر با یک لیست است. لیست مولود شامال سه عنصر از نوع رشته است:
$ yamlpy revisions/01_03_yaml/18/test.yml [{'example_1': ['item_1', 'item_2', 'item_3']}, {'example_2': ['item_4', 'item_5', 'item_6']}]
در بازبینی نوزدهم باز هم سعی شده تا یک مثال نسبتا پیچیده تر آورده شود:
$ cat revisions/01_03_yaml/19/test.yml --- example_dictionary_1: - example_dictionary_2: - 1 - 2 - 3 - example_dictionary_2: - 4 - 5 - 6 - example_dictionary_4: - 7 - 8 - 9 # Every YAML file should end with three dots ...
در این مدل در بالاترین سطح یک دیکشنری داریم که شامل یک کلید است. مقدار این کلید یک لیست که سه عنصر دارد و هر عنصر یک دیکشنری است. این دیکشنری خود شامل یک کلید است که مقدار آن یک لیست با سه عنصر اینتجر است.
$ yamlpy revisions/01_03_yaml/19/test.yml {'example_dictionary_1': [{'example_dictionary_2': [1, 2, 3]}, {'example_dictionary_2': [4, 5, 6]}, {'example_dictionary_4': [7, 8, 9]}]}
در این مثال ما تا پنج سطح به عمق رفته ایم. ۱- دیشکنری، ۲- لیست ، ۳- دیکشنری و ۴- لیست و در آخرین سطح عناصر لیست که از نوع اینتیجر هستند.
در بازبینی بیستم برای درک بهتر ساختار یک فایل yaml من لیستی از چهار کارگردان محبوبم را تهیه کرده ام:
cat revisions/01_03_yaml/20/test.yml --- - Clint Eastwood - Quentin Tarantino - Martin Scorsese - Mohsen Makhmalbaf # Every YAML file should end with three dots ...
که خروجی آن در دستور yamlpy یقینا به صورت زیر خواهد بود:
$ yamlpy revisions/01_03_yaml/20/test.yml ['Clint Eastwood', 'Quentin Tarantino', 'Martin Scorsese', 'Mohsen Makhmalbaf']
در بازبینی بیست و یک همین لیست کارگردانها را کمی تغییر دادهایم:
cat revisions/01_03_yaml/21/test.yml --- - Clint Eastwood: Born: 1930 Best Movie: Million Dollar Baby - Quentin Tarantino: Born: 1963 Best Movie: Pulp Fiction - Martin Scorsese: Born: 1942 Best Movie: Casino - Mohsen Makhmalbaf: Born: 1957 Best Movie: Sex & Philosophy # Every YAML file should end with three dots ...
عناصر لیست (کارگردانها) اکنون خود کلید یک دیکشنری هستند که مقدار آنها یک دیکشنری دیگر شامل دو کلید یکی سال تولد و دیگری بهتری اثرشان از نظر نگارنده است:
$ yamlpy revisions/01_03_yaml/21/test.yml [{'Clint Eastwood': {'Best Movie': 'Million Dollar Baby', 'Born': 1930}}, {'Quentin Tarantino': {'Best Movie': 'Pulp Fiction', 'Born': 1963}}, {'Martin Scorsese': {'Best Movie': 'Casino', 'Born': 1942}}, {'Mohsen Makhmalbaf': {'Best Movie': 'Sex & Philosophy', 'Born': 1957}}]
در بازبینی بیست و دوم یک مثال پیچیده تر آورده شده:
cat revisions/01_03_yaml/22/test.yml --- - Aston Martin: year_founded: 1913 website: astonmartin.com founded_by: - Lionel Martin - Robert Bamford - Fiat: year_founded: 1899 website: fiat.com founded_by: - Giovanni Agnelli - Ford: year_founded: 1903 website: ford.com founded_by: - Henry Ford - Vauxhall: year_founded: 1857 website: vauxhall.co.uk founded_by: - Alexander Wilson # Every YAML file should end with three dots ...
لطفا با دستور yamlpy این فایل را از بازبینی ۲۲ بررسی و آنالیز کنید و در صورت تمایل به عنوان تمرین در کامنت توضیح خود را بنویسید و یا به ایمیل من ارسال کنید.
لینک قسمتهای قبلی این سری آموزش به شرح ذیل است:
دیدگاهتان را بنویسید