L'API Namespaces ti consente di attivare facilmente la multitenancy nella tua applicazione, semplicemente selezionando una stringa dello spazio dei nomi per ogni tenant
in appengine_config.py
utilizzando il pacchetto namespace_manager
.
Impostazione dello spazio dei nomi corrente
Puoi ottenere, impostare e convalidare gli spazi dei nomi
utilizzando il pacchetto namespace_manager
.
Il gestore dello spazio dei nomi consente di impostare uno spazio dei nomi corrente per le API abilitate per gli spazi dei nomi. Imposti un attuale spazio dei nomi in anticipo
in appengine_config.py
e Datastore e memcache utilizzano automaticamente questo spazio dei nomi.
La maggior parte degli sviluppatori App Engine utilizzerà il proprio dominio Google Workspace (precedentemente G Suite) come spazio dei nomi corrente. Google Workspace ti consente di eseguire il deployment dell'app su qualsiasi dominio di tua proprietà, in modo da poter utilizzare facilmente questo meccanismo per configurare diversi spazi dei nomi per domini diversi. Poi, puoi utilizzare questi spazi dei nomi distinti per separare i dati nei domini. Per ulteriori informazioni, consulta Mappatura di domini personalizzati.
Il seguente esempio di codice mostra come impostare lo spazio dei nomi corrente sul dominio Google Workspace utilizzato per mappare l'URL. È importante notare che questa stringa sarà la stessa per tutti gli URL mappati tramite lo stesso dominio Google Workspace.
Per impostare un ambito in Python, utilizza il sistema di configurazione di App Engine appengine_config.py
nella directory principale dell'applicazione. Il seguente semplice esempio mostra come utilizzare il tuo dominio Google Workspace come spazio dei nomi corrente:
from google.appengine.api import namespace_manager
# Called only if the current namespace is not set.
def namespace_manager_default_namespace_for_request():
# The returned string will be used as the Google Apps domain.
return namespace_manager.google_apps_namespace()
Se non specifichi un valore per namespace
, lo spazio dei nomi viene impostato su una stringa vuota. La stringa namespace
è arbitraria, ma limitata anche a un massimo di 100 caratteri alfanumerici, punti, trattini bassi e trattini. In modo più esplicito, le stringhe dello spazio dei nomi devono corrispondere all'espressione regolare [0-9A-Za-z._-]{0,100}
.
Per convenzione, tutti gli spazi dei nomi che iniziano con "_
" (underscore) sono riservati all'uso di sistema. Questa regola dello spazio dei nomi di sistema non viene applicata, ma potresti facilmente riscontrare conseguenze negative non definite se non la segui.
appengine_config.py
, consulta Configurazione del modulo Python.
Evitare fughe di dati
Uno dei rischi comunemente associati alle app multitenant è il pericolo che i dati vengano divulgati tra gli spazi dei nomi. Le fughe di dati indesiderate possono derivare da molte fonti, tra cui:
- Utilizzo degli spazi dei nomi con API App Engine che non supportano ancora gli spazi dei nomi. Ad esempio, Blobstore non supporta gli spazi dei nomi. Se utilizzi gli spazi dei nomi con Blobstore, devi evitare di utilizzare query di Blobstore per le richieste degli utenti finali o chiavi di Blobstore provenienti da origini non attendibili.
- Utilizzo di un supporto di archiviazione esterno (anziché memcache e Datastore), tramite
URL Fetch
o un altro meccanismo, senza fornire uno schema di compartimentalizzazione per i namespace. - Impostazione di uno spazio dei nomi in base al dominio email di un utente. Nella maggior parte dei casi, non vuoi che tutti gli indirizzi email di un dominio accedano a uno spazio dei nomi. L'utilizzo del dominio email impedisce inoltre alla tua applicazione di utilizzare uno spazio dei nomi finché l'utente non ha eseguito l'accesso.
Deployment degli spazi dei nomi
Le sezioni seguenti descrivono come eseguire il deployment degli spazi dei nomi con altri strumenti e API di App Engine.
Creazione di spazi dei nomi per ogni utente
Alcune applicazioni devono creare spazi dei nomi in base all'utente. Se vuoi suddividere i dati a livello di utente per gli utenti che hanno eseguito l'accesso, ti consigliamo di utilizzare
User.user_id()
, che restituisce un ID univoco e permanente per l'utente. Il seguente esempio di codice mostra come utilizzare l'API Users a questo scopo:
from google.appengine.api import users
def namespace_manager_default_namespace_for_request():
# assumes the user is logged in.
return users.get_current_user().user_id()
In genere, le app che creano spazi dei nomi in base all'utente forniscono anche pagine di destinazione specifiche a utenti diversi. In questi casi, l'applicazione deve fornire uno schema URL che indichi quale pagina di destinazione mostrare a un utente.
Utilizzo degli spazi dei nomi con Datastore
Per impostazione predefinita, Datastore utilizza l' impostazione dello spazio dei nomi corrente nel gestore dello spazio dei nomi per le richieste di Datastore. L'API applica questo spazio dei nomi corrente agli oggetti
Key
o Query
al momento della loro creazione. Pertanto, devi fare attenzione se un'applicazione memorizza oggetti Key
o Query
in formati serializzati, poiché lo spazio dei nomi viene mantenuto in queste serializzazioni.
Se utilizzi oggetti Key
e Query
deserializzati, assicurati che funzionino come previsto. La maggior parte delle applicazioni semplici che utilizzano Datastore (put
/query
/get
) senza utilizzare altri meccanismi di archiviazione funzionerà come previsto impostando lo spazio dei nomi corrente prima di chiamare qualsiasi API Datastore.
Gli oggetti Query
e Key
mostrano i seguenti comportamenti unici per quanto riguarda gli spazi dei nomi:
- Gli oggetti
Query
eKey
ereditano lo spazio dei nomi corrente al momento della loro creazione, a meno che non venga impostato uno spazio dei nomi esplicito. - Quando un'applicazione crea un nuovo
Key
da un elemento precedente, il nuovoKey
eredita lo spazio dei nomi dell'elemento precedente.
Utilizzo degli spazi dei nomi con Memcache
Per impostazione predefinita, memcache utilizza lo spazio dei nomi corrente del gestore dello spazio dei nomi per le richieste memcache. Nella maggior parte dei casi, non è necessario impostare esplicitamente uno spazio dei nomi in memcache, perché ciò potrebbe introdurre bug imprevisti.
Tuttavia, esistono alcune istanze univoche in cui è opportuno impostare esplicitamente uno spazio dei nomi in memcache. Ad esempio, l'applicazione potrebbe avere dati comuni condivisi in tutti gli spazi dei nomi (ad esempio una tabella contenente i codici paese).
Utilizzando l'API Python per memcache, puoi recuperare lo spazio dei nomi corrente dal gestore dello spazio dei nomi o impostarlo esplicitamente quando crei il servizio memcache. L'esempio seguente imposta lo spazio dei nomi in modo esplicito quando memorizzi un valore in memcache:// Store an entry to the memcache explicitly memcache.add("key", data, namespace='abc')
Utilizzo degli spazi dei nomi con la coda di attività
Per impostazione predefinita, le code di coda push utilizzano lo spazio dei nomi corrente impostato nel gestore dello spazio dei nomi al momento della creazione dell'attività. Nella maggior parte dei casi, non è necessario impostare esplicitamente uno spazio dei nomi nella coda delle attività, in quanto ciò potrebbe introdurre bug imprevisti.
I nomi delle attività vengono condivisi in tutti gli spazi dei nomi. Non puoi creare due attività con lo stesso nome, anche se utilizzano spazi dei nomi diversi. Se vuoi utilizzare lo stesso nome attività per più spazi dei nomi, puoi semplicemente aggiungere ogni spazio dei nomi al nome dell'attività.
Quando una nuova attività chiama il metodo
add()
della coda di attività, la coda di attività copia lo spazio dei nomi corrente e (se applicabile) il dominio Google Workspace dal gestore dello spazio dei nomi. Quando l'attività viene eseguita, vengono ripristinati lo spazio dei nomi corrente e lo spazio dei nomi di Google Workspace.
Se lo spazio dei nomi corrente non è impostato nella richiesta di origine (in altre parole, se get_namespace()
restituisce ''
), puoi utilizzare set_namespace()
per impostare lo spazio dei nomi corrente per l'attività.
In alcuni casi è opportuno impostare esplicitamente uno spazio dei nomi per un'attività che funzioni in tutti gli spazi dei nomi. Ad esempio, puoi creare un'attività che aggrega le statistiche di utilizzo in tutti gli spazi dei nomi. Potresti quindi impostare esplicitamente lo spazio dei nomi dell'attività.
Utilizzo degli spazi dei nomi con Blobstore
Blobstore non è segmentato per spazio dei nomi. Per preservare uno spazio dei nomi in Blobstore, devi accedere a Blobstore tramite un supporto di archiviazione che sia a conoscenza dello spazio dei nomi (attualmente solo memcache, Datastore e coda di attività). Ad esempio, se il Key
di un blob è archiviato in un'entità Datastore, puoi accedervi con un Key
o Query
di Datastore che conosce lo spazio dei nomi.
Se l'applicazione accede a Blobstore tramite chiavi archiviate in uno spazio di archiviazione consapevole dello spazio dei nomi, Blobstore stesso non deve essere segmentato per spazio dei nomi. Le applicazioni devono evitare perdite di blob tra gli spazi dei nomi:
- Non utilizzare
BlobInfo.gql()
per le richieste degli utenti finali. Puoi utilizzare le query BlobInfo per le richieste amministrative (ad esempio per generare report su tutti i blob delle applicazioni), ma l'utilizzo per le richieste degli utenti finali potrebbe comportare fughe di dati perché tutti i record BlobInfo non sono suddivisi in base al nome dello spazio dei nomi. - Non utilizzare chiavi Blobstore di origini non attendibili.
Impostazione degli spazi dei nomi per le query Datastore
Nella console Google Cloud, puoi impostare lo spazio dei nomi per le query Datastore.
Se non vuoi utilizzare quello predefinito, seleziona lo spazio dei nomi che vuoi utilizzare dal menu a discesa.
Utilizzo degli spazi dei nomi con Bulk Loader
Il caricamento collettivo supporta un flag --namespace=NAMESPACE
che consente di specificare lo spazio dei nomi da utilizzare. Ogni spazio dei nomi viene gestito separatamente e, se vuoi accedere a tutti gli spazi dei nomi, dovrai eseguirne l'iterazione.
Utilizzare gli spazi dei nomi con la ricerca
Quando crei una nuova istanza di Index
, questa viene assegnata allo spazio dei nomi corrente per impostazione predefinita:
# set the current namespace
namespace_manager.set_namespace("aSpace")
index = search.Index(name="myIndex")
# index namespace is now fixed to "aSpace"
Puoi anche assegnare uno spazio dei nomi in modo esplicito nel costruttore:
index = search.Index(name="myIndex", namespace="aSpace")
Una volta creata una specifica dell'indice, il relativo spazio dei nomi non può essere modificato:
# change the current namespace
namespace_manager.set_namespace("anotherSpace")
# the namespaceof 'index' is still "aSpace" because it was bound at create time
index.search('hello')