Data Management (DMS) met à disposition un langage spécifique au domaine (DSL) pour définir des règles de sécurité dans les workflows de développement de bases de données. Ces règles DSL vous permettent de contrôler la soumission des instructions SQL, de gérer le routage des approbations et de bloquer ou signaler comme risquées certaines opérations.
Fonctionnement
Une règle de sécurité suit une structure IF-THEN ou IF-THEN-ELSE. Lorsqu'une condition est satisfaite, DMS exécute l'action correspondante.
Structure de base :
if <condition>
then <action>
end
Structure étendue avec plusieurs branches :
if <condition 1>
then <action 1>
elseif <condition 2>
then <action 2>
[else <action 3>]
end
Chaque règle doit contenir exactement une condition if. Elle peut comporter zéro ou plusieurs branches elseif et au plus une clause else. Si aucune branche ne correspond et qu'aucune clause else n'est définie, DMS n'entreprend aucune action.
Composants du DSL
Une règle de sécurité se compose de trois éléments fondamentaux : les clauses conditionnelles, les clauses d'action et les fonctions prédéfinies.
Clauses conditionnelles
Une clause conditionnelle s'évalue à true ou false. Elle est constituée d'un ou plusieurs des éléments suivants :
Facteurs — variables système prédéfinies représentant le contexte au moment de l'évaluation (par exemple, le type d'instruction SQL ou le nombre de lignes affectées)
Opérateurs — symboles servant à comparer ou tester des valeurs
Connecteurs —
ANDetOR, qui combinent plusieurs expressions
L'opérateur AND a une priorité supérieure à celle de OR. Ces deux connecteurs ont une priorité inférieure à celle des opérateurs. Utilisez des parenthèses pour modifier l'ordre d'évaluation par défaut.
Exemple : Dans l'expression 1 <= 0 or 1 == 1, DMS évalue séparément 1 <= 0 et 1 == 1, puis applique l'opérateur OR. Pour rendre la priorité explicite : (1 <= 0) == true.
Opérateurs
Les opérateurs relient les facteurs et les constantes dans les expressions conditionnelles. Les opérateurs suivants sont pris en charge :
| Opérateur | Description | Exemple |
|---|---|---|
== |
Égal à | 1 == 1 |
!= |
Différent de | 1 != 2 |
> |
Supérieur à | @fac.insert_rows > 1000 |
>= |
Supérieur ou égal à | @fac.insert_rows >= 1000 |
< |
Inférieur à | @fac.insert_rows < 100 |
<= |
Inférieur ou égal à | @fac.insert_rows <= 100 |
in |
Appartient à un tableau | 'a' in ['a', 'b', 'c'] |
not in |
N'appartient pas à un tableau | 'a' not in ['a', 'b', 'c'] |
matchs |
Correspond à une expression régulière | 'idx_aa' matchs 'idx_\\w+' |
not matchs |
Ne correspond pas à une expression régulière | 'idx_aa' not matchs 'idx_\\w+' |
isBlank |
La valeur est vide | '' isBlank |
isNotBlank |
La valeur n'est pas vide | '' isNotBlank |
Échappement des barres obliques inverses dans les expressions régulières : Pour inclure une barre oblique inverse littérale (\) dans un modèle regex, échappez-la avec une autre barre oblique inverse. Par exemple, écrivez idx_\\w+ pour faire correspondre idx_\w+.
Facteurs
Les facteurs sont des variables prédéfinies fournissant le contexte lors de l'évaluation des règles de sécurité, telles que le type d'instruction SQL, le nombre de lignes affectées ou si la cible est une base de données logique. Utilisez-les dans les clauses conditionnelles pour rédiger des règles basées sur les métadonnées réelles de l'opération.
Un nom de facteur utilise le format @fac.<display-name>. DMS met à disposition différents facteurs selon les points de contrôle de chaque module.
| Facteur | Description |
|---|---|
@fac.env_type |
Type d'environnement. Exemples de valeurs : DEV, PRODUCT. Consultez la rubrique Modification du type d'environnement d'une instance. |
@fac.sql_type |
Type d'instruction SQL. Exemples de valeurs : UPDATE, INSERT. |
@fac.detail_type |
Type de ticket de modification de données. Voir les valeurs valides ci-dessous. |
@fac.is_logic |
Indique si la base de données cible est une base de données logique. |
@fac.extra_info |
Autres informations relatives au ticket. Non utilisé actuellement. |
@fac.is_ignore_affect_rows |
Indique s'il faut ignorer la validation du nombre de lignes. |
@fac.insert_rows |
Nombre de lignes à insérer. |
@fac.update_delete_rows |
Nombre de lignes à mettre à jour ou à supprimer. |
@fac.max_alter_table_size |
Taille du plus grand tablespace contenant la table à modifier. |
@fac.is_has_security_column |
Indique si l'instruction SQL implique des champs sensibles. |
@fac.security_column_list |
Champs sensibles impliqués dans l'instruction SQL. |
@fac.risk_level |
Niveau de risque de l'opération. |
@fac.risk_reason |
Raison du niveau de risque attribué. |
@fac.ref_schema_names |
Liste des noms de bases de données sélectionnés dans le ticket. |
Valeurs valides pour @fac.detail_type :
| Valeur | Type de ticket |
|---|---|
COMMON |
Normal Data Modify |
CHUNK_DML |
Lockless Change |
PROCEDURE |
Programmable Object |
CRON_CLEAR_DATA |
History Data Clean |
BIG_FILE |
Large Data Import |
Exemple : Vérifier si une instruction SQL est de type DML :
@fac.sql_type == 'DML'
Clauses d'action
Une action définit ce que DMS fait lorsqu'une condition est remplie. Les noms d'action utilisent le format @act.<display-name>. DMS fournit différentes actions selon les points de contrôle de chaque module.
| Action | Description |
|---|---|
@act.allow_submit |
Impose la soumission des instructions SQL à exécuter via un ticket. |
@act.allow_execute_direct |
Autorise l'exécution des instructions SQL dans SQL Console. |
@act.forbid_execute |
Bloque l'exécution des instructions SQL. |
@act.mark_risk |
Marque l'opération avec un niveau de risque et un message personnalisé. Exemple : @act.mark_risk 'middle' 'Medium risk: online environment' |
@act.do_not_approve |
Spécifie l'ID d'un modèle d'approbation. Consultez la rubrique Configuration des processus d'approbation. |
@act.choose_approve_template |
|
@act.choose_approve_template_with_reason |
Fonctions prédéfinies
Les fonctions prédéfinies peuvent être utilisées dans les clauses conditionnelles et les clauses d'action. Les noms de fonction utilisent le format @fun.<display-name>.
| Fonction | Entrée | Sortie | Description |
|---|---|---|---|
@fun.concat |
Plusieurs chaînes | Chaîne | Concatène plusieurs chaînes en une seule. |
@fun.char_length |
Une chaîne | Entier | Renvoie la longueur d'une chaîne. |
@fun.is_char_lower |
Une chaîne | Booléen | Renvoie true si toutes les lettres sont en minuscules. |
@fun.is_char_upper |
Une chaîne | Booléen | Renvoie true si toutes les lettres sont en majuscules. |
@fun.array_size |
Un tableau | Entier | Renvoie le nombre d'éléments dans un tableau. |
@fun.add |
Plusieurs valeurs numériques | Numérique | Additionne plusieurs valeurs. |
@fun.sub |
Deux valeurs numériques | Numérique | Soustrait la deuxième valeur de la première. |
@fun.between |
Trois valeurs : cible, borne inférieure, borne supérieure | Booléen | Renvoie true si la cible se situe dans la plage fermée [inférieure, supérieure]. Prend en charge les types NUMERIC, DATE et TIME. |
@fun.current_datetime |
Aucun | Chaîne | Renvoie la date et l'heure actuelles au format yyyy-MM-dd HH:mm:ss. |
@fun.current_date |
Aucun | Chaîne | Renvoie la date actuelle au format yyyy-MM-dd. |
@fun.current_time |
Aucun | Chaîne | Renvoie l'heure actuelle au format HH:mm:ss. |
@fun.is_contain_str |
Deux chaînes | Booléen | Renvoie true si la première chaîne contient la seconde. |
@fun.listEqualIgnoreOrder |
Deux listes de chaînes | Booléen | Renvoie true si les deux listes contiennent les mêmes chaînes, indépendamment de l'ordre ou de la casse. |
Exemples sélectionnés :
Concaténation de chaînes :
@fun.concat('d', 'm', 's')
// Output: 'dms'
@fun.concat('[Development standards] Enter a comment for the [', @fac.column_name, '] field.')
// Output: a reminder message with the field name inserted
Vérification si une valeur numérique se situe dans une plage :
@fun.between(@fac.export_rows, 2001, 100000)
// Returns true if the number of exported rows is between 2,001 and 100,000
@fun.between(@fun.current_datetime(), '2019-10-31 00:00:00', '2019-11-04 00:00:00')
// Returns true if the current date and time fall within the specified window
Vérification de l'égalité des listes :
@fun.listEqualIgnoreOrder(@fac.perm_type, ['QUERY'])
// Returns true if only the query permission is requested
@fun.listEqualIgnoreOrder(@fac.perm_type, ['CORRECT', 'EXPORT'])
// Returns true if both the change and export permissions are requested
Exemples
Limiter le nombre d'instructions SQL par ticket
Bloquez la soumission si un ticket contient plus de 1 000 instructions SQL :
if
@fac.sql_count > 1000
then
@act.reject_execute 'The number of SQL statements in a ticket cannot exceed 1,000.'
end
Si le décompte dépasse 1 000, DMS rejette le ticket et affiche le message.
Autoriser uniquement les instructions DML
Autorisez la soumission uniquement lorsque toutes les instructions SQL sont des opérations DML :
if
@fac.sql_type in ['UPDATE', 'DELETE', 'INSERT', 'INSERT_SELECT']
then
@act.allow_submit
end