Automatisation de la configuration IAM à partir des spécifications OpenAPI 2.0 à l'aide d'ObjectScript
Importance
La gestion de l'IAM peut s'avérer fastidieuse lorsqu'elle est effectuée manuellement, en particulier lorsque vos API sont déjà bien documentées à l'aide des spécifications OpenAPI (Swagger). Ne serait-il pas formidable de pouvoir générer automatiquement des services et des itinéraires Kong directement à partir de vos spécifications OpenAPI?
C'est exactement ce que fait cette méthode ObjectScript : elle lit une spécification OpenAPI 2.0 stockée dans le bloc XData de votre classe de spécification et génère un vfichier YAML compatible avec decK** qui peut être utilisé pour synchroniser votre configuration IAM.
Cette approche:
- Réduit les erreurs de configuration manuelle
- Maintient votre passerelle synchronisée avec votre spécification API
- Accélère le déploiement et l'intégration
Conditions préalables:
- Une plateforme InterSystems IRIS ou basée sur IRIS
- InterSystems API Manager
- Outil CLI Deck
Principe de fonctionnement de la méthode
La méthode ConvertOpenAPIXDataToDeckYAML:
- Lit la spécification OpenAPI à partir d'un bloc
XDatanomméOpenAPIdans une classe particulière. - Analyse le JSON dans un objet dynamique.
- Extrait les points de terminaison et les méthodes HTTP.
- Génère un fichier YAML qui définit:
- Un service Kong orienté vers l'hôte API et le chemin d'accès de base
- Des itinéraires pour chaque point de terminaison
- Un plug-in de limite de débit sur chaque itinéraire (optimisation facultative)
Exemple de classe de spécifications
Vous pouvez utiliser l'exemple de classe de spécifications ci-dessous ou utiliser la classe générée à partir de la publication du fichier de spécifications inclus dans l'article précédent dont le lien se trouve ci-dessous
Class MyApp.spec
{
XData OpenAPI [ MimeType = application/json ]
{
{
"swagger": "2.0",
"host": "api.example.com",
"basePath": "/v1",
"paths": {
"/users": {
"get": { "summary": "Get users" },
"post": { "summary": "Create user" }
},
"/products": {
"get": { "summary": "Get products" }
}
}
}
}
}
La méthode et son utilisation
Vous trouverez ci-dessous la méthode ClassMethod. Vous pouvez bien sûr la modifier pour l'adapter à vos besoins.
/// Transformation de données OpenAPI XData en Deck YAML
ClassMethod ConvertOpenAPIXDataToDeckYAML(specClassName As %String, outputFilePath As %String = "") As %Status
{
Try {
// Lecture du bloc XData nommé "OpenAPI"
Set reader = ##class(%Dictionary.XDataDefinition).%OpenId(specClassName _ "||OpenAPI")
If reader = "" {
Write "Error: XData block 'OpenAPI' not found in class ", specClassName, !
//Quit $$$ERROR
}
// Lecture du contenu du flux dans une chaîne
Set stream = reader.Data
Set specJSON = ""
While 'stream.AtEnd {
Set specJSON = specJSON _ stream.ReadLine()
}
// Appel test
//Do ##class(ConsentAPI.Utils).ConvertOpenAPIXDataToDeckYAML("SpecAPI.spec")
// Analyse le JSON dans un objet dynamique
Set spec = ##class(%DynamicObject).%FromJSON(specJSON)
// Initialisation de la structure YAML
Set deckYAML = "services:" _ $CHAR(13)
// Extraction de l'hôte et de basePath
Set host = $PIECE($SYSTEM, ":", 1)
Set basePath = spec.basePath
// Création d'un bloc de service
Set deckYAML = deckYAML _ " - name: " _ host _ $CHAR(13)
Set deckYAML = deckYAML _ " url: "_$c(34)_"http://" _ host _ basePath _$c(34)_ $CHAR(13)
Set deckYAML = deckYAML _ " routes:" _ $CHAR(13)
// Itération sur les chemins
Set pathIter = spec.paths.%GetIterator()
While pathIter.%GetNext(.key, .value) {
Set pathKey = key
Set path = spec.paths.key
Set routeName = $REPLACE(key , "/", "")
Set deckYAML = deckYAML _ " - name: " _ routeName _ $CHAR(13)
Set deckYAML = deckYAML _ " strip_path: false"_$CHAR(13)
Set deckYAML = deckYAML _ " preserve_host: false"_$CHAR(13)
Set deckYAML = deckYAML _ " paths:"_$CHAR(13)
Set deckYAML = deckYAML _ " - " _ pathKey _ $CHAR(13)
Set deckYAML = deckYAML _ " methods:"_$CHAR(13)
Set methodIter = value.%GetIterator()
While methodIter.%GetNext(.key, .value) {
Set methodKey = key
Set deckYAML = deckYAML _ " - " _ $ZCONVERT(methodKey, "U") _ $CHAR(13)
}
Set deckYAML = deckYAML _ " plugins:"_$CHAR(13)
Set deckYAML = deckYAML _ " - name: " _ "rate-limiting" _ $CHAR(13)
Set deckYAML = deckYAML _ " config:"_$CHAR(13)
Set deckYAML = deckYAML _ $REPLACE($J("",12),"",$C(32))_"minute: 20" _ $CHAR(13)
Set deckYAML = deckYAML _ $REPLACE($J("",12),"",$C(32))_"hour: 500" _ $CHAR(13)
}
// Envoi au fichier ou à la console
If outputFilePath '= "" {
Set file = ##class(%Stream.FileCharacter).%New()
Set file.Filename = outputFilePath
Do file.Write(deckYAML)
Do file.%Save()
Write "YAML saved to: ", outputFilePath, !
} Else {
Write deckYAML, !
}
//Quit $$$OK
} Catch ex {
Write "Error: ", ex.DisplayString(), !
//Quit ex.AsStatus()
}
}
À l'aide de cette méthode et en ayant un fichier YAML généré, il suffit de l'appeler depuis une session de terminal, AKA IRIS CLI.
Do ##class(MyUtils.APIConverter).ConvertOpenAPIXDataToDeckYAML("MyApp.spec", "/tmp/deck.yaml")
Ou vous pouvez simplement écrire le yaml sur la console
Do ##class(MyUtils.APIConverter).ConvertOpenAPIXDataToDeckYAML("MyApp.spec")
Étapes suivantes
Une fois le fichier YAML généré, vous pouvez utiliser decK pour le synchroniser avec votre instance IAM:
deck gateway sync --workspace <WorkSpace> deck.yml
Cela permettra de créer ou de mettre à jour des services et des itinéraires dans IAM selon vos spécifications.
Conclusion
Cette méthode comble l'écart entre le développement basé sur les spécifications et la configuration des passerelles. Elle est idéale pour les équipes qui utilisent InterSystems IRIS ou HealthShare et IAM dans leur architecture.
Souhaitez-vous l'étendre?
- Incluez des plugins d'authentification
- Générez plusieurs services basés sur des balises
Tenez-moi au courant via les commentaires ou contactez-moi si vous avez besoin d'aide pour la personnaliser!