Tous les produits
Search
Centre de documentation

CDN:Utiliser la CLI EdgeScript pour gérer les scripts

Dernière mise à jour :Aug 18, 2026

La CLI EdgeScript (ES) vous permet de publier des scripts depuis votre machine locale vers les environnements de test et de production, ainsi que de les interroger, modifier ou supprimer sans passer par la console.

Prérequis

Avant de commencer, assurez-vous de disposer des éléments suivants :

  • Un utilisateur RAM disposant des autorisations CDN requises

  • L'AccessKey ID et l'AccessKey Secret de l'utilisateur RAM

  • Python 2 installé sur votre machine locale

Configurer la CLI

Créer les fichiers du projet

  1. Créez un dossier pour le projet, par exemple cdn-api.

  2. Dans ce dossier, créez un fichier nommé aliyun.ini pour stocker les identifiants de votre utilisateur RAM :

    [Credentials]
    accesskeyid = <your-access-key-id>
    accesskeysecret = <your-access-key-secret>
  3. Dans le même dossier, créez un fichier nommé es.py et collez-y le script Python suivant :

    #!/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)

Configurer les identifiants

Exécutez la commande suivante pour enregistrer votre paire AccessKey dans aliyun.ini :

python ./es.py config --id=<your-access-key-id> --secret=<your-access-key-secret>

Vérifiez que les identifiants ont bien été enregistrés :

cat aliyun.ini

Résultat attendu :

[Credentials]
accesskeyid = <your-access-key-id>
accesskeysecret = <your-access-key-secret>

Gérer les scripts

Toutes les commandes utilisent le paramètre action pour spécifier l'opération. Remplacez <domain> par votre nom de domaine accéléré dans chaque commande.

Publier un script

Publiez un script dans l'environnement de test pour le valider avant sa mise en production :

./es.py action=push_test_env domain=<domain> rule='{"pos":"head","pri":"10","rule_path":"./m3u8.es","enable":"on"}'

Pour publier un script directement dans l'environnement de production :

./es.py action=push_product_env domain=<domain> rule='{"pos":"head","pri":"10","rule_path":"./m3u8.es","enable":"on","configid":"12345"}'

Le paramètre rule accepte les champs suivants :

Champ Obligatoire Description Valeurs valides Par défaut
pos Oui Position d'exécution du script head, foot
pri Oui Priorité parmi les scripts situés à la même position. 0 représente la priorité la plus élevée, 999 la plus faible. 0999
enable Oui Indique si le script est actif on, off
rule Oui Contenu du script. Lors de l'utilisation de la CLI, fournissez plutôt rule_path ; la CLI lit le fichier et transmet son contenu via ce champ. Chaîne de contenu de script
rule_path CLI uniquement Chemin d'accès au fichier EdgeScript local. La CLI lit ce fichier et soumet son contenu en tant que champ rule. Chaîne de chemin de fichier
configid Obligatoire lors de la modification ID de configuration d'un script existant. À omettre lors de la création ; requis lors de la modification. ID de configuration
brk Non Empêche l'exécution des scripts suivants si ce script s'exécute on, off off
testip Non Restreint l'exécution du script aux requêtes provenant d'une adresse IP client spécifique Chaîne d'adresse IP Vide (toutes les requêtes)
option Non Champ d'extension. Définissez-le sur _es_dbg=<signature> pour activer le débogage des en-têtes de réponse. _es_dbg=<signature>
Vous pouvez spécifier plusieurs paramètres rule dans une seule commande pour publier plusieurs scripts simultanément.

À propos des ID de configuration

Un ID de configuration (configid) est généré automatiquement lorsque vous créez un script pour un nom de domaine. Il n'est pas nécessaire d'en fournir un lors de la création d'un script. Pour modifier un script existant, interrogez-le d'abord afin d'obtenir son ID de configuration, puis incluez "configid":"<configid>" dans le champ rule. Pour plus de détails, consultez la rubrique Notes d'utilisation sur ConfigId.

Interroger les scripts

Listez tous les scripts EdgeScript pour un nom de domaine :

# Staging environment
./es.py action=query_test_env domain=<domain>

# Production environment
./es.py action=query_product_env domain=<domain>

Supprimer un script

Supprimez un script à l'aide de son ID de configuration. Exécutez d'abord une requête si vous ne connaissez pas l'ID de configuration.

# Staging environment
./es.py action=del_test_env domain=<domain> configid=<configid>

# Production environment
./es.py action=del_product_env domain=<domain> configid=<configid>

Promouvoir les scripts de test vers la production

Après avoir validé les scripts dans l'environnement de test, publiez-les en production :

./es.py action=publish_test_env domain=<domain>

Restaurer les scripts

Restaurez l'environnement de test à sa configuration précédente :

./es.py action=rollback_test_env domain=<domain>

Déboguer les scripts

Pour activer le débogage des en-têtes de réponse, définissez le champ option sur _es_dbg=<signature> lors de la publication d'un script :

./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"}'

Vous pouvez également activer le débogage depuis la console Alibaba Cloud CDN si celle-ci prend en charge WebIDE.

Une fois activé, incluez _es_dbg=<signature> dans l'en-tête de la requête lors de l'envoi d'une requête de test. La réponse inclut l'en-tête de débogage suivant :

X-DEBUG-ES-TRACE-RULE-{Script ID}

La valeur de trace suit ce format : _<row-number>_<function-name>(<input>):<return-value>{_<execution-duration>}

Cela affiche le flux de contrôle du script, y compris chaque appel de fonction, ses entrées, sa valeur de retour et son temps d'exécution.

Étapes suivantes