1. Введение​

Kusion Configuration Language (KCL) — это простой и удобный в использовании язык конфигурации, на котором пользователи могут просто написать повторно используемый код конфигурации.

В этой первой лабораторной работе мы узнаем, как написать простую конфигурацию с помощью KCL.

Изучение этого лабораторного кода требует только базовых знаний в области программирования, а опыт работы с Python сделает его еще проще.

Чему мы научимся

  1. Напишите простые конфигурации ключ-значение программируемым способом.
  2. Напишите простую логику в коде KCL
  3. Запись коллекций в коде KCL
  4. Тестирование и отладка с помощью кода KCL
  5. Используйте встроенную поддержку в коде KCL
  6. Делитесь и повторно используйте код KCL
  7. Написать конфиг с динамическими входными аргументами

2. Напишите пары ключ-значение

Создайте простую конфигурацию, создав my_config.k, мы можем заполнить следующий код без строгого формата, который описывает конфигурацию развертывания.

cpu = 256
memory = 512
image = "nginx:1.14.2"
service = "my-service"

В приведенном выше коде процессор и память объявлены как значения int, а изображение и служба — строковые литералы.

Запустив KCL, мы увидим сгенерированные данные в формате yaml, как показано ниже:

KCL-команда:

kcl my_config.k

Стандартный вывод:

cpu: 256
memory: 512
image: nginx:1.14.2
service: my-service

Экспортируемая переменная неизменяема по умолчанию, поэтому после ее объявления мы не можем изменить ее где-либо еще.

3. Напишите простую логику

Иногда мы хотим написать логику в конфигурации, тогда мы можем использовать:

  • Изменяемая и неэкспортируемая переменная, начинающаяся с '_'
  • Оператор if-else

Неэкспортируемая переменная означает, что она не будет отображаться в выходном YAML и может быть назначена несколько раз.

Вот пример, показывающий, как настроить ресурс с условиями.

KCL-команда:

kcl my_config.k
_priority = 1 # a non-exported and mutable variable
_cpu = 256 # a non-exported and mutable variable

if _priority == 1:
    _cpu = 256
elif _priority == 2:
    _cpu = 512
elif _priority == 3:
    _cpu = 1024
else:
    _cpu = 2048

cpu = _cpu
memory = _cpu * 2
image = "nginx:1.14.2"
service = "my-service"

Запустив KCL, мы увидим сгенерированные данные в формате yaml, как показано ниже:

kcl my_config.k

Стандартный вывод:

cpu: 256
memory: 512
image: nginx:1.14.2
service: my-service

.. примечание:: KCL имеет богатую поддержку операторов и строковых функций-членов, пожалуйста, прочитайте руководство и спецификацию для получения более подробной информации.

4. Напишите коллекции

Мы можем использовать коллекции для представления сложных типов данных. Коллекции, которые уже поддерживаются:

  • список
  • диктовать
_priority = 1  # a non-exported and mutable variable
_cpu = 256  # a non-exported and mutable variable

if _priority == 1:
    _cpu = 256
elif _priority == 2:
    _cpu = 512
elif _priority == 3:
    _cpu = 1024
else:
    _cpu = 2048

cpu = _cpu
memory = _cpu * 2
command = ["nginx"] # a list
labels = {run = "my-nginx"} # a dict
image = "nginx:1.14.2"
service = "my-service"

Запустите с kcl, мы увидим сгенерированные данные в формате yaml, как показано ниже:

KCL-команда:

kcl my_config.k

Стандартный вывод:

cpu: 512
memory: 1024
command:
    - nginx
labels:
    run: my-nginx
image: nginx:1.14.2
service: my-service

Дополнительные сведения о типе даты сбора и функциях-членах см. в руководстве и спецификации.

5. Добавить элементы в коллекции

Мы можем комбинировать логические выражения, понимания, срезы, объединения и другие характеристики для динамического добавления элементов в коллекцию.

_priority = 1 # a non-exported and mutable variable
_cpu = 256 # a non-exported and mutable variable
_env = "pre-prod"

if _priority == 1:
    _cpu = 256
elif _priority == 2:
    _cpu = 512
elif _priority == 3:
    _cpu = 1024
else:
    _cpu = 2048

cpu = _cpu
memory = _cpu * 2
_command = ["nginx"] # a list
_command = _command + ["-f", "file"]  # Append itemsinto command using + operator to contact two lists
command = [c.lower() for c in _command]  # Take eachelement in the list to lowercase
_labels = {
    run = "my-nginx"
    if _env:
        env = _env  # Append a dict key-value pair when the _env is not None/Undefined or empty using if expressions
} # a dict
labels = _labels
image = "nginx:1.14.2"
service = "my-service"

Запустите с kcl, мы увидим сгенерированные данные в формате yaml, как показано ниже:

kcl my_config.k

Стандартный вывод:

cpu: 256
memory: 512
command:
- nginx
- -f
- file
labels:
  run: my-nginx
image: nginx:1.14.2
service: my-service

6. Напишите Assert

Чтобы сделать код проверяемым и надежным, мы можем проверить данные конфигурации с помощью утверждений.

_priority = 1 # a non-exported and mutable variable
_cpu = 256 # a non-exported and mutable variable

if _priority == 1:
    _cpu = 256
elif _priority == 2:
    _cpu = 512
elif _priority == 3:
    _cpu = 1024
else:
    _cpu = 2048

cpu = _cpu
memory = _cpu * 2
command = ["nginx"] # a list
labels = {run = "my-nginx"} # a dict
image = "nginx:1.14.2"
service = "my-service"
assert "env" in labels, "env label is a must"
assert cpu >= 256, "cpu cannot be less than 256"

Запустите с KCL, мы увидим сбой eval с сообщением об ошибке, как показано ниже:

kcl my_config.k

Штдерр:

Assertion failure: env label is a must.

После добавления пары env:pre-prod в метки мы получим вывод:

cpu: 512
memory: 1024
command:
    - nginx
labels:
    run: my-nginx
    env: pre-prod
image: nginx:1.14.2
service: my-service

7. Используйте удобную встроенную поддержку

Более того, мы можем использовать встроенные функции для отладки или упрощения кода.

_priority = 1  # a non-exported and mutable variable
_cpu = 256  # a non-exported and mutable variable

if _priority == 1:
    _cpu = 256
elif _priority == 2:
    _cpu = 512
elif _priority == 3:
    _cpu = 1024
else:
    _cpu = 2048

_name = "nginx"
# exported variables
cpu = _cpu
memory = _cpu * 2
command = [_name] # a list
labels = {
    run = "my-{}".format(_name)
    env = "pre-prod"
} # a dict
image = "{}:1.14.2".format(_name) # string format
service = "my-service"

# debugging
print(labels) # debugging by print

# test
assert len(labels) > 0, "labels can't be empty" # uselen() to get list length
assert "env" in labels, "env label is a must"
assert cpu >= 256, "cpu cannot be less than 256"

В этом примере показано, как мы используем функции format(), len(), print() для настройки конфигурации.

Запустив KCL, мы увидим сгенерированные данные в формате yaml, как показано ниже:

KCL-команда:

kcl my_config.k

Стандартный вывод:

cpu: 512
memory: 1024
command:
    - nginx
labels:
    run: my-nginx
    env: pre-prod
image: nginx:1.14.2
service: my-service
run: my-nginx
env: pre-prod

Примечание: дополнительные встроенные функции и модули можно увидеть в спецификации/модуле.

8. Повторное использование переменных в другом модуле

Чтобы сделать наш код хорошо организованным, мы можем просто разделить наш код на my_config.k и my_config_test.k.

Данные конфигурации, определенные в my_config.k,

_priority = 1  # a non-exported and mutable variable
_cpu = 256  # a non-exported and mutable variable

if _priority == 1:
    _cpu = 256
elif _priority == 2:
    _cpu = 512
elif _priority == 3:
    _cpu = 1024
else:
    _cpu = 2048
_name = "nginx"

# exported variables
cpu = _cpu
memory = _cpu * 2
command = [_name] # a list
labels = {
    run = "my-{}".format(_name)
    env = "pre-prod"
} # a dict
image = "{}:1.14.2".format(_name) # string format
service = "my-service"

И тестовый код, определенный в my_config_test.k, в который мы можем импортировать my_config.k:

import my_config

# debugging
print(my_config.labels) # debugging by print

# test
assert len(my_config.labels) > 0, "labels can't beempty" # use len() to get list length
assert "env" in my_config.labels, "env label is a must"
assert my_config.cpu >= 256, "cpu cannot be less than256"

9. Конфигурация с входными аргументами

Иногда нам нужно получить внешний ввод через параметры динамически от конечного пользователя или платформы.

В этом случае мы можем передать priority и env по запросу:

  • Передать аргументы: -D priority=1 -D env=pre-prod
  • Получить значение по ключевому слову option в коде KCL
_priority = option("priority") # a non-exported and mutable variable
_env = option("env") # a non-exported and mutable variable
_cpu = 256 # a non-exported and mutable variable

if _priority == 1:
    _cpu = 256
elif _priority == 2:
    _cpu = 512
elif _priority == 3:
    _cpu = 1024
else:
    _cpu = 2048

_name = "nginx"
# exported variables
cpu = _cpu
memory = _cpu * 2
command = [_name] # a list
labels = {
    run = "my-{}".format(_name)
    env = _env
} # a dict
image = "{}:1.14.2".format(_name) # string format
service = "my-service"

Запустив KCL, мы увидим сгенерированные данные в формате yaml, как показано ниже:

kcl -D priority=2 -D env=pre-prod my_config.k

Стандартный вывод:

cpu: 512
memory: 1024
command:
    - nginx
labels:
    run: my-nginx
    env: pre-prod
image: nginx:1.14.2
service: my-service

10. Упростите логическое выражение с помощью Dict

Когда нам нужно написать сложную логику, мы можем использовать dict для упрощения написания логики.

_priority = option("priority") # a non-exported and mutable variable
_env = option("env") # a non-exported and mutable variable
_priorityCpuMap = {
    "1" = 256
    "2" = 512
    "3" = 1024
}
# Using a dict to simplify logic and the default value is 2048
_cpu = _priorityCpuMap[_priority] or 2048
_name = "nginx"
# exported variables
cpu = _cpu
memory = _cpu * 2
command = [_name] # a list
labels = {
    run = "my-{}".format(_name)
    env = _env
} # a dict
image = "{}:1.14.2".format(_name) # string format
service = "my-service"

Запустив KCL, мы увидим сгенерированные данные в формате yaml, как показано ниже:

KCL-команда:

kcl -D priority=2 -D env=pre-prod my_config.k

Стандартный вывод:

cpu: 512
memory: 1024
command:
    - nginx
labels:
    run: my-nginx
    env: pre-prod
image: nginx:1.14.2
service: my-service

11. Последний шаг

Поздравляем!

Мы завершили первый урок о KCL, и мы использовали KCL для замены нашего текстового файла ключ-значение, чтобы получить лучшую поддержку программирования.

Пожалуйста, проверьте лабораторию кода схемы сейчас, чтобы узнать, как написать расширенную конфигурацию совместно с механизмом KCL schema.