CLI EdgeScript (ES) memungkinkan Anda menerbitkan skrip dari mesin lokal ke lingkungan staging dan produksi, serta melakukan kueri, modifikasi, atau penghapusan tanpa menggunakan Konsol.
Prasyarat
Sebelum memulai, pastikan Anda telah memiliki:
Pengguna RAM dengan izin CDN yang diperlukan
ID AccessKey dan Rahasia AccessKey milik Pengguna RAM tersebut
Python 2 yang terinstal di mesin lokal Anda
Siapkan CLI
Buat file proyek
Buat folder untuk proyek, misalnya,
cdn-api.Di dalam folder tersebut, buat file bernama
aliyun.iniuntuk menyimpan kredensial Pengguna RAM Anda:[Credentials] accesskeyid = <your-access-key-id> accesskeysecret = <your-access-key-secret>Di dalam folder yang sama, buat file bernama
es.pydan tempel skrip Python berikut:#!/usr/bin/python # -*- coding:utf-8 -*- import sys, os import urllib, urllib2 import base64 import hmac import hashlib from hashlib import sha1 import time import uuid import json from optparse import OptionParser import ConfigParser import traceback import urllib2 access_key_id = ''; access_key_secret = ''; cdn_server_address = 'https://cdn.aliyuncs.com' CONFIGFILE = os.getcwd() + '/aliyun.ini' CONFIGSECTION = 'Credentials' cmdlist = ''' 1. Publish the ES rule to the simulated environment or production environment ./es.py action=push_test_env domain=<domain> rule='{"pos":"<head|foot>","pri":"0-999","rule_path":"<the es code path>","enable":"<on|off>"}' ./es.py action=push_product_env domain=<domain> rule='{"pos":"<head|foot>","pri":"0-999","rule_path":"<the es code path>","enable":"<on|off>","configid":"<configid>"}' 2. Query the ES rule in the simulated environment or production environment ./es.py action=query_test_env domain=<domain> ./es.py action=query_product_env domain=<domain> 3. Delete the ES rule in the simulated environment or production environment ./es.py action=del_test_env domain=<domain> configid=<configid> ./es.py action=del_product_env domain=<domain> configid=<configid> 4. Publish the ES rule from the simulated to production environment, or Rollback the ES rule in the simulated environment ./es.py action=publish_test_env domain=<domain> ./es.py action=rollback_test_env domain=<domain> ''' def percent_encode(str): res = urllib.quote(str.decode(sys.stdin.encoding).encode('utf8'), '') res = res.replace('+', '%20') res = res.replace('*', '%2A') res = res.replace('%7E', '~') return res def compute_signature(parameters, access_key_secret): sortedParameters = sorted(parameters.items(), key=lambda parameters: parameters[0]) canonicalizedQueryString = '' for (k,v) in sortedParameters: canonicalizedQueryString += '&' + percent_encode(k) + '=' + percent_encode(v) stringToSign = 'GET&%2F&' + percent_encode(canonicalizedQueryString[1:]) h = hmac.new(access_key_secret + "&", stringToSign, sha1) signature = base64.encodestring(h.digest()).strip() return signature def compose_url(user_params): timestamp = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()) parameters = { \ 'Format' : 'JSON', \ 'Version' : '2018-05-10', \ 'AccessKeyId' : access_key_id, \ 'SignatureVersion' : '1.0', \ 'SignatureMethod' : 'HMAC-SHA1', \ 'SignatureNonce' : str(uuid.uuid1()), \ 'Timestamp' : timestamp, \ } for key in user_params.keys(): parameters[key] = user_params[key] signature = compute_signature(parameters, access_key_secret) parameters['Signature'] = signature url = cdn_server_address + "/?" + urllib.urlencode(parameters) return url def make_request(user_params, quiet=False): url = compose_url(user_params) try: req = urllib2.Request(url) r = urllib2.urlopen(req) except urllib2.HTTPError, err: print "Response Code:\n=============" print err body=err.read() body_json = json.loads(body) body_str =json.dumps(body_json,indent=4) print "\nResponse Info:\n==============" print body_str return if r.getcode() == 200: print "Response Code:\n=============\n200 OK" print "\nResponse Info:\n==============" body=r.read() body_json = json.loads(body) body_str =json.dumps(body_json,indent=4) print body_str def configure_accesskeypair(args, options): if options.accesskeyid is None or options.accesskeysecret is None: print("config miss parameters, use --id=[accesskeyid] --secret=[accesskeysecret]") sys.exit(1) config = ConfigParser.RawConfigParser() config.add_section(CONFIGSECTION) config.set(CONFIGSECTION, 'accesskeyid', options.accesskeyid) config.set(CONFIGSECTION, 'accesskeysecret', options.accesskeysecret) cfgfile = open(CONFIGFILE, 'w+') config.write(cfgfile) cfgfile.close() def setup_credentials(): config = ConfigParser.ConfigParser() try: config.read(CONFIGFILE) global access_key_id global access_key_secret access_key_id = config.get(CONFIGSECTION, 'accesskeyid') access_key_secret = config.get(CONFIGSECTION, 'accesskeysecret') except Exception, e: print traceback.format_exc() print("can't get access key pair, use config --id=[accesskeyid] --secret=[accesskeysecret] to setup") sys.exit(1) def parse_args(user_params): req_args = {} if user_params['action'] == 'push_test_env' or user_params['action'] == 'push_product_env': if not user_params.has_key('domain') or not user_params.has_key('rule'): parser.print_help() sys.exit(0) data = [] for rule in user_params['rule']: rule_cfg = { 'functionId' : 180, 'functionName' : 'edge_function', 'functionArgs' : [] } for k in rule: arg_cfg = {} if k == 'configid': rule_cfg['configId'] = int(rule[k]) elif k == 'rule_path': try: f = open(rule[k], "r") code = f.read() except IOError: print "io error" sys.exit(0) else: f.close() arg_cfg['argName'] = 'rule' arg_cfg['argValue'] = code rule_cfg['functionArgs'].append(arg_cfg) else: arg_cfg['argName'] = k arg_cfg['argValue'] = rule[k] rule_cfg['functionArgs'].append(arg_cfg) data.append(rule_cfg) rule_str = json.dumps(data) if user_params['action'] == 'push_test_env': req_args = {'Action':'SetCdnDomainStagingConfig', 'DomainName':user_params['domain'], 'Functions':rule_str} else: req_args = {'Action':'BatchSetCdnDomainConfig', 'DomainNames':user_params['domain'], 'Functions':rule_str} elif user_params['action'] == 'query_test_env': if not user_params.has_key('domain'): parser.print_help() sys.exit(0) req_args = {'Action':'DescribeCdnDomainStagingConfig', 'DomainName':user_params['domain'], 'FunctionNames':'edge_function'} elif user_params['action'] == 'query_product_env': if not user_params.has_key('domain'): parser.print_help() sys.exit(0) req_args = {'Action':'DescribeCdnDomainConfigs', 'DomainName':user_params['domain'], 'FunctionNames':'edge_function'} elif user_params['action'] == 'del_test_env': if not user_params.has_key('domain') or not user_params.has_key('configid'): parser.print_help() sys.exit(0) req_args = {'Action':'DeleteSpecificStagingConfig', 'DomainName':user_params['domain'], 'ConfigId':user_params['configid']} elif user_params['action'] == 'del_product_env': if not user_params.has_key('domain') or not user_params.has_key('configid'): parser.print_help() sys.exit(0) req_args = {'Action':'DeleteSpecificConfig', 'DomainName':user_params['domain'], 'ConfigId':user_params['configid']} elif user_params['action'] == 'publish_test_env': if not user_params.has_key('domain'): parser.print_help() sys.exit(0) req_args = {'Action':'PublishStagingConfigToProduction', 'DomainName':user_params['domain'], 'FunctionName':'edge_function'} elif user_params['action'] == 'rollback_test_env': if not user_params.has_key('domain'): parser.print_help() sys.exit(0) req_args = {'Action':'RollbackStagingConfig', 'DomainName':user_params['domain'], 'FunctionName':'edge_function'} else: parser.print_help() sys.exit(0) return req_args if __name__ == '__main__': parser = OptionParser("%s Action=action Param1=Value1 Param2=Value2 %s\n" % (sys.argv[0], cmdlist)) parser.add_option("-i", "--id", dest="accesskeyid", help="specify access key id") parser.add_option("-s", "--secret", dest="accesskeysecret", help="specify access key secret") (options, args) = parser.parse_args() if len(args) < 1: parser.print_help() sys.exit(0) if args[0] == 'help': parser.print_help() sys.exit(0) if args[0] != 'config': setup_credentials() else: #it's a configure id/secret command configure_accesskeypair(args, options) sys.exit(0) user_params = {} idx = 1 if sys.argv[1].lower().startswith('action='): _, value = sys.argv[1].split('=') user_params['action'] = value idx = 2 else: parser.print_help() sys.exit(0) for arg in sys.argv[idx:]: try: key, value = arg.split('=', 1) if key == 'rule': # push_test_env / push_product_env if not user_params.has_key('rule'): user_params['rule'] = [] user_params['rule'].append(json.loads(value)) else: user_params[key.strip()] = value except ValueError, e: print(e.read().strip()) raise SystemExit(e) req_args = parse_args(user_params) make_request(req_args)
Konfigurasi kredensial
Jalankan perintah berikut untuk menyimpan pasangan AccessKey Anda di aliyun.ini:
python ./es.py config --id=<your-access-key-id> --secret=<your-access-key-secret>Verifikasi bahwa kredensial telah tersimpan:
cat aliyun.iniOutput yang diharapkan:
[Credentials]
accesskeyid = <your-access-key-id>
accesskeysecret = <your-access-key-secret>Mengelola skrip
Semua perintah menggunakan parameter action untuk menentukan operasi. Ganti <domain> dengan nama domain yang dipercepat Anda pada setiap perintah.
Terbitkan skrip
Dorong skrip ke lingkungan staging untuk mengujinya sebelum dipublikasikan:
./es.py action=push_test_env domain=<domain> rule='{"pos":"head","pri":"10","rule_path":"./m3u8.es","enable":"on"}'Untuk mendorong skrip langsung ke lingkungan produksi:
./es.py action=push_product_env domain=<domain> rule='{"pos":"head","pri":"10","rule_path":"./m3u8.es","enable":"on","configid":"12345"}'Parameter rule menerima bidang-bidang berikut:
| Field | Required | Description | Valid values | Default |
|---|---|---|---|---|
pos | Yes | Posisi tempat skrip dijalankan | head, foot | — |
pri | Yes | Prioritas di antara skrip pada posisi yang sama. 0 adalah prioritas tertinggi, 999 adalah prioritas terendah. | 0–999 | — |
enable | Yes | Apakah skrip aktif | on, off | — |
rule | Yes | Konten skrip. Saat menggunakan CLI, gunakan rule_path sebagai gantinya; CLI membaca file dan meneruskan isinya sebagai bidang ini. | String konten skrip | — |
rule_path | CLI only | Path ke file EdgeScript lokal. CLI membaca file ini dan mengirimkan isinya sebagai bidang rule. | String path file | — |
configid | Required when modifying | ID konfigurasi skrip yang sudah ada. Abaikan saat membuat; wajib disertakan saat memodifikasi. | Configuration ID | — |
brk | No | Hentikan eksekusi skrip berikutnya jika skrip ini dieksekusi | on, off | off |
testip | No | Batasi eksekusi skrip hanya untuk permintaan dari alamat IP client tertentu | String alamat IP | Kosong (semua permintaan) |
option | No | Bidang ekstensi. Atur menjadi _es_dbg=<signature> untuk mengaktifkan debugging header respons. | _es_dbg=<signature> | — |
Anda dapat menentukan beberapa parameter rule dalam satu perintah untuk mendorong beberapa skrip sekaligus.Tentang ID konfigurasi
ID konfigurasi (configid) dibuat secara otomatis saat Anda membuat skrip untuk nama domain. Anda tidak perlu menyediakannya saat membuat skrip. Untuk memodifikasi skrip yang sudah ada, lakukan kueri terlebih dahulu untuk mendapatkan ID konfigurasinya, lalu sertakan "configid":"<configid>" dalam bidang rule. Untuk detail selengkapnya, lihat Catatan penggunaan ConfigId.
Kueri skrip
Daftar semua skrip EdgeScript untuk nama domain:
# Lingkungan staging
./es.py action=query_test_env domain=<domain>
# Lingkungan produksi
./es.py action=query_product_env domain=<domain>Hapus skrip
Hapus skrip berdasarkan ID konfigurasinya. Lakukan kueri terlebih dahulu jika Anda tidak mengetahui ID konfigurasinya.
# Lingkungan staging
./es.py action=del_test_env domain=<domain> configid=<configid>
# Lingkungan produksi
./es.py action=del_product_env domain=<domain> configid=<configid>Tingkatkan skrip staging ke produksi
Setelah memvalidasi skrip di lingkungan staging, tingkatkan ke produksi:
./es.py action=rollback_test_env domain=<domain>Kembalikan skrip
Kembalikan lingkungan staging ke konfigurasi sebelumnya:
./es.py action=rollback_test_env domain=<domain>Debug skrip
Untuk mengaktifkan debugging header respons, atur bidang option menjadi _es_dbg=<signature> saat mendorong skrip:
./es.py action=push_test_env domain=<domain> rule='{"pos":"head","pri":"10","rule_path":"./m3u8.es","enable":"on","configid":"12345","option":"_es_dbg=123"}'Anda juga dapat mengaktifkan debugging dari Konsol CDN Alibaba Cloud jika mendukung WebIDE.
Setelah diaktifkan, sertakan _es_dbg=<signature> dalam header permintaan saat mengirim permintaan uji. Respons akan menyertakan header debug berikut:
X-DEBUG-ES-TRACE-RULE-{Script ID}Nilai jejak mengikuti format berikut: _<nomor-baris>_<nama-fungsi>(<input>):<nilai-kembali>{_<durasi-eksekusi>}
Ini menunjukkan alur kendali skrip, termasuk setiap pemanggilan fungsi, input-nya, nilai kembali, dan waktu eksekusi.
Langkah berikutnya
Contoh penggunaan CLI ES untuk mengelola skrip: Ikuti contoh lengkap pembuatan, pengujian, dan penerbitan skrip m3u8.es untuk memblokir permintaan M3U8.
Catatan penggunaan ConfigId: Pelajari cara ID konfigurasi dibuat, dikueri, dan digunakan.