От хранилища до CDN через Management API
Задайте ACDN_API_TOKEN, ACDN_ZONE_NAME (уникальное имя в нижнем регистре) и ACDN_FILE (путь к локальному файлу). Пример на Python 3 создаёт платные ресурсы, загружает публичный объект и подключает CDN. Используется только стандартная библиотека. Храните ключи в секрете и не запускайте пример повторно вслепую после таймаута: сначала проверьте ресурсы через API или панель.
import json
import os
from pathlib import Path
from urllib.parse import quote
from urllib.request import Request, urlopen
api = 'https://acdn.uz/api/user'
token = os.environ['ACDN_API_TOKEN']
name = os.environ['ACDN_ZONE_NAME']
file = Path(os.environ['ACDN_FILE'])
def management(method, path, body=None):
request = Request(api + path, method=method, headers={
'Authorization': 'Bearer ' + token,
'Accept': 'application/json',
'Content-Type': 'application/json',
}, data=json.dumps(body).encode() if body is not None else None)
with urlopen(request, timeout=60) as response:
return json.load(response)['data']
storage = management('POST', '/storage-zones', {
'name': name, 'storage_region': 'uz',
})
credentials = management('GET', '/storage-zones/credentials/' + storage['id'])
object_path = quote(file.name, safe='')
upload = Request(
credentials['endpoint'] + '/' + credentials['bucket'] + '/' + object_path,
method='PUT',
headers={'AccessKey': credentials['access_key']},
data=file.read_bytes(),
)
with urlopen(upload, timeout=120) as response:
print('Upload:', response.status)
cdn = management('POST', '/pull-zones', {
'name': name, 'source_type': 'storage_zone',
'source_storage_zone_name': storage['name'], 'tier': 'std',
})
print('Delivery URL:', 'https://' + cdn['hostname'] + '/' + object_path)
CDN URL может стать доступен не сразу: конфигурации нужно время на применение. Для загрузки через S3 вместо простого HTTP API создайте S3-ключ и следуйте руководству по подключению S3.
DNS-записи и очистка кеша после деплоя
Замените DOMAIN_ID и PULL_ZONE_ID на идентификаторы своих ресурсов. Изменение DNS и очистка кеша требуют подтверждённой почты. Тип записи 16 означает TXT. Purge асинхронно очищает весь кеш зоны и может увеличить нагрузку на origin; объекты в хранилище не удаляются.
curl --fail-with-body --request POST \
'https://acdn.uz/api/user/dns-zones/entries/DOMAIN_ID' \
--header "Authorization: Bearer $ACDN_API_TOKEN" \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '{"name":"_acme-challenge","type":16,"ttl":60,"value":"challenge-value"}'
curl --fail-with-body --request POST \
'https://acdn.uz/api/user/pull-zones/purge/PULL_ZONE_ID' \
--header "Authorization: Bearer $ACDN_API_TOKEN" \
--header 'Accept: application/json'
Настройки, проверка доменов и ротация ключей описаны в полном справочнике API.
Примеры конфигурации
Замените EXPIRES_UNIX на будущую Unix-метку времени и вычислите TOKEN_VALUE именно для неё по руководству по токен-аутентификации.
Токенизированный URL с query-параметрами:
https://cdn.example.uz/video/intro.mp4?acdn_token=TOKEN_VALUE&expires=EXPIRES_UNIX
Токенизированный URL с path-параметрами:
https://cdn.example.uz/acdn_token=TOKEN_VALUE&expires=EXPIRES_UNIX/video/intro.mp4
Edge rule для шардирования origin по первому сегменту пути:
Condition:
field = request_url
match = any
values = ["/node-*"]
Action:
action = override_origin_url
value = "https://node%{Path.0}.origin.example"
Edge rule для добавления upstream API key header:
Condition:
field = request_url
match = any
values = ["/media/*"]
Action:
action = set_request_header
header = "X-Origin-Key"
value = "your-secret-value"