[PYTHON] [Alibaba Cloud] Faites quelque chose comme SSI même avec OSS / Function Compute

TL;DR Dernière fois, le HTML avec SSI (include virtual) décrit dans AWS est stocké dans un compartiment spécifique de S3 et les sources de l'inclusion sont combinées avec Lambda. J'ai créé un mécanisme pour le stocker dans un autre seau, mais c'est la version Alibaba Cloud de celui-ci.

Ce que je voulais faire

Le service OSS (Object Storage Service) étant un service d'hébergement de site statique, il n'est en principe pas possible de traiter dynamiquement côté serveur. Bien entendu, le côté CDN (Alibaba Cloud CDN), qui est la destination de la mise en cache par la suite, ne peut pas non plus être utilisé.

Dans ce cas, je pense que la méthode standard consiste à créer un environnement de développement local, à les conserver dans des fichiers séparés localement et à les combiner lors de la compilation, mais OSS + est un site existant qui utilisait à l'origine SSI. Malheureusement, ce flux ne peut pas être introduit dans tous les projets, y compris lors du transfert vers CDN.

Donc, si SSI a été utilisé à l'origine, j'ai essayé de l'ajuster du côté d'Alibaba Cloud afin qu'il puisse être utilisé tel quel sans le remplacer tel quel.

Ce que j'ai fait

(En principe, les paramètres de RAM et de KMS, qui sont l'IAM de la version Alibaba Cloud, ont été complétés.)

Fondamentalement, il est personnalisé pour Alibaba Cloud en fonction de l'article précédent. [AWS] Faites des choses similaires à SSI avec S3 / Lambda Je pense que cet article de SB Cloud est utile pour configurer Alibaba Cloud. Manipuler le stockage d'objets avec le service événementiel Fucntion Compute

Constitution

La configuration est la même que la dernière fois. Donc, les seuls services que j'utilise sont OSS et Function Compute, si vous avez besoin du CDN Cloud Alibaba. SSI_alibaba.png

Méthode de réglage

OSS Dans la version Alibaba Cloud, il n'y a qu'un seul compartiment pour télécharger des fichiers. Le processus est divisé en deux, un répertoire pour temp et un répertoire à usage public.

Godet pour public / temporaire

Le nom peut être n'importe quoi. Cette fois, c'est «oss-ssi-include».

Chaque paramètre

On suppose que les autorisations d'accès sont définies de manière appropriée.

Création d'un répertoire public et d'un répertoire temporaire

Créez le répertoire public dist et le répertoire temporaire src dans le compartiment en cliquant sur le bouton" Créer un répertoire ".

Function Compute

Function Compute détecte l'événement PUT, et si SSI (Server Side Include) est décrit dans le fichier HTML téléchargé dans le répertoire src /, Function Compute effectue le traitement d'inclusion et le répertoire dist /. Créez une fonction dans laquelle stocker.

Code de fonction

import json
import os
import logging
import oss2 
import re
import urllib.parse

logger = logging.getLogger()
logger.setLevel(logging.INFO)

OSS_ENDPOINT        = "oss-ap-northeast-1.aliyuncs.com"
DEST_BUCKET_NAME    = "oss-ssi-include"

def handler(event, context):
    logger.info('## ENVIRONMENT VARIABLES')
    logger.info(os.environ)
    logger.info('## EVENT')
    logger.info(event)
    
    creds = context.credentials
    auth = oss2.StsAuth(creds.accessKeyId, creds.accessKeySecret, creds.securityToken)
    evt = json.loads(event)
 
    #Réécrire ci-dessous
    input_bucket = oss2.Bucket(auth, OSS_ENDPOINT, DEST_BUCKET_NAME)

    logger.info('## INPUT BUKET')
    logger.info(input_bucket)
    
    input_key = urllib.parse.unquote_plus(evt['events'][0]['oss']['object']['key'])
    logger.info('## INPUT KEY')
    logger.info(input_key)

    try:
        #Obtenir le fichier d'entrée
        response = input_bucket.get_object(input_key)
        logger.info(response)

        #Sortie de fichier
        output_key    = re.sub('^src/','dist/',input_key)
        logger.info('## OUTPUT KEY')
        logger.info(output_key)

        if not input_key.endswith('.html'):
            logger.info(response)
            input_bucket.put_object(output_key, response)

        else:
            input_html = response.read().decode('utf-8')
            logger.info('## input_html')
            logger.info(input_html)
            output_html = input_html
            #Obtenir la description SSI
            include_path_base = re.findall(r'<!--#include virtual="/(.*?)" -->.*?\n', input_html, flags=re.DOTALL)
            logger.info('## PATH BASE')
            logger.info(include_path_base)
            if len(include_path_base) > 0:
                for path in include_path_base:
                    include_path = path
                    logger.info('## PATH')
                    logger.info(include_path)
            
                    #Obtenir le fichier SSI
                    try:
                        include = input_bucket.get_object('src/' + include_path)
                        include_html = include.read().decode('utf-8')
                        #Exécutez SSI
                        output_html = output_html.replace('<!--#include virtual="/' + include_path + '" -->', include_html)
                    except ClientError:
                        pass
            

            input_bucket.put_object(output_key, output_html)

    except Exception as e:
        logger.info(e)
        raise e

Autres réglages

Réglage du déclencheur

Type de déclencheur: déclencheur OSS Nom du déclencheur: put Source de l'événement: acs:oss:ap-northeast-1:xxxxxxxxxxxxxxxxx:ossname Événements: oss: ObjectCreated: PutObject, oss: ObjectCreated: PostObject Règle de déclenchement: préfixe src / Opération de rôle: sélectionnez un rôle existant Rôle existant: Le rôle est OK avec la stratégie suivante définie dans la RAM.

{
    "Version": "1",
    "Statement": [
        {
            "Action": [
                "fc:InvokeFunction"
            ],
            "Resource": "*",
            "Effect": "Allow"
        }
    ]
}

en conclusion

Dernière fois, le HTML avec SSI (include virtual) décrit dans AWS est stocké dans un compartiment spécifique de S3 et les sources de l'inclusion sont combinées avec Lambda. J'ai créé un mécanisme pour le stocker dans un autre seau, mais je l'ai préparé car il était nécessaire de le faire dans Alibaba Cloud pour diverses raisons.

Contrairement à la version AWS, le fichier est téléchargé dans le répertoire temporaire → CloudCompute le traite → Le fichier est stocké dans le répertoire public, donc si vous voulez le rendre plus facile à utiliser, il est préférable de livrer le fichier stocké dans le répertoire public à CDN Je trouve ça bien.

En outre, lorsque vous essayez d'obtenir des informations sur Alibaba Cloud au Japon, le [Blog de l'ingénieur] de SB Cloud (https://www.sbcloud.co.jp/archive/category/techblog) est recommandé. J'ai également utilisé celui-ci comme référence.

Mais est-ce important? .. Tout cela vient du terrain.

Recommended Posts

[Alibaba Cloud] Faites quelque chose comme SSI même avec OSS / Function Compute
Faites quelque chose comme fuzzing avec acceptableRegex.py
Je veux améliorer l'efficacité avec Python même dans un système expérimental (3) Je veux faire quelque chose comme Excel avec Pandas
Connectez votre base de données SQL Server à Alibaba Cloud Function Compute à l'aide de Python