Extensions de services

Extensions de services

Explorer

Documentation

L’intégration des systèmes d’accès nécessite des possibilités de configuration extrêmement étendues. Les extensions de services sont de courts programmes Golang qui se fixent aux points d’extension au sein de l’orchestrateur afin de modifier ou d’étendre les fonctionnalités. Elles donnent aux administrateurs la possibilité de personnaliser le comportement de l’orchestrateur en fonction des besoins particuliers de leur intégration.

Points d’extension de services

Tous les principaux composants de l’orchestrateur exposent l’extension de services. Veuillez consulter les documents spécifiques aux composants pour plus de détails sur les points d’extension exacts.

Environnement de développement local

Les extensions de services peuvent être écrites dans Maverics UI ou avec n’importe quel éditeur de texte. Si vous préférez utiliser un environnement de développement local pour profiter des fonctionnalités communes des EDI, telles que l’auto-complétion, le linting, la compilation de code, etc., reportez-vous aux instructions figurant dans le référentiel de la bibliothèque des extension de services.

Documentation Go Library

L’orchestrateur propose une bibliothèque destinée à faciliter le développement d’extensions et à accéder aux fonctionnalités sous-jacentes de l’orchestrateur. Par exemple, il est possible que vous souhaitiez vous connecter à un fournisseur d’identité, interroger un fournisseur d’attributs ou extraire des secrets d’un magasin de secrets. Pour savoir quelles sont les fonctionnalités disponibles et comment les utiliser, veuillez consulter la documentation de la bibliothèque.

Options de configuration

Le code de l’extension de services peut être défini directement dans le fichier de configuration à l’aide d’un bloc de code, ou dans un fichier séparé.

Nom de la fonction

funcName est un identifiant unique correspondant au nom de la fonction de l’extension de services.Les noms de fonctions en langage Go ne doivent pas contenir d’espaces, et la première lettre doit être en majuscule pour pouvoir être exportée (voir idiomes).

Code

code correspond au code Golang de l’extension de services spécifiée directement dans le fichier de configuration.

Fichier

fichier est le chemin d’accès au système de fichiers d’un fichier d’extension de services Go.

Metadata

metadata représente un ensemble varié de paires clé-valeur qui peut être mis à la disposition d’une extension donnée. Les valeurs peuvent être référencées à partir du code Go, ce qui rend les extensions de services plus flexibles et la configuration plus logique.

ℹ️
Les métadonnées ne sont pas partagées entre différentes extensions de services.

Paquets protégés autorisés

allowedProtectedPackages est un tableau de chaînes de caractères qui permet de spécifier les paquets protégés dans les extensions de services.

Les paquets suivants sont actuellement protégés et ne sont pas activés par défaut :

  • os
  • os/exec
⚠️
Le fait d’autoriser des paquets protégés dans les extensions de services peut constituer un risque pour la sécurité, car cela expose les fonctionnalités au niveau du système d’exploitation. À utiliser avec précaution.

Exemples

Définition d’une extension de services dans Config

Pour spécifier une extension de service à l’aide d’un code, utilisez la construction YAML scalaire de bloc |+.

apps:
  - name: exampleOIDCApp
    type: oidc
    # ...
    authentication:
      isAuthenticatedSE:
        funcName: IsAuthenticated
        code: |+
          package main

          import (
            "net/http"

            "github.com/strata-io/service-extension/orchestrator"
            "github.com/strata-io/service-extension/session"
          )

          func IsAuthenticated(api orchestrator.Orchestrator, _ http.ResponseWriter, req *http.Request) bool {
            return false
          }          

Définition des extensions de services dans des fichiers séparés

La gestion des extensions de services est souvent plus facile lorsqu’elles sont rédigées et enregistrées sous la forme de fichiers .go séparés. Utilisez le fichier pour spécifier l’emplacement du système de fichiers.

apps:
  - name: exampleOIDCApp
    type: oidc
    # ...
    authentication:
      authenticateSE:
        funcName: IsAuthenticated
        file: /etc/maverics/extensions/auth.go

Le fichier /etc/maverics/extensions/auth.go contient le code de l’extension de services :

package main

import (
    "net/http"

    "github.com/strata-io/service-extension/orchestrator"
)

func IsAuthenticated(orchestrator.Orchestrator, http.ResponseWriter, *http.Request) bool {
    return false
}

Extension de services utilisant des métadonnées

L’exemple suivant définit un attribut booléen debug: false dans les métadonnées :

authentication:
  isAuthenticatedSE:
    funcName: IsAuthenticated
    file: /etc/maverics/extensions/auth.go
    metadata:
      debug: true
  authenticateSE:
    funcName: Authenticate
    file: /etc/maverics/extensions/auth.go
    metadata:
      debug: false

Il peut ensuite être référencé dans /etc/maverics/extensions/auth.go :

package main

import (
    "net/http"

    "github.com/strata-io/service-extension/orchestrator"
)

func IsAuthenticated(api orchestrator.Orchestrator, _ http.ResponseWriter, _ *http.Request) bool {
    var (
        metadata = api.Metadata()
        logger = api.Logger()
    )
	session, err := api.Session()
	if err != nil {
		logger.Error("se", "unable to retrieve session", "error", err.Error())
		return false
	}

    debugEnabled := metadata["debug"] == true // Will be set to 'true'

	isOktaAuth, err := session.GetString("okta.authenticated")
	if err != nil {
		logger.Error("se", "unable to retrieve session value 'okta.authenticated'", "error", err.Error())
		return false
    }
	if isOktaAuth == "true" {
		if debugEnabled {
			logger.Debug("se", "user is not authenticated")
		}
		return true
	}
    if debugEnabled {
        logger.Debug("se", "user is authenticated")
    }
    return false
}

func Authenticate(api orchestrator.Orchestrator, rw http.ResponseWriter, req *http.Request) {
    var (
        metadata = api.Metadata()
        logger = api.Logger()
    )

    debugEnabled := metadata["debug"] == true  // Will be set to 'false'

    okta, err := api.IdentityProvider("okta")
    if err != nil {
        http.Error(rw, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
        logger.Error("se", "missing okta IDP", "error", err.Error())
        return
    }

    if debugEnabled {
        logger.Debug("se", "logging in via okta")
    }

    okta.Login(rw, req)
}

Extension de services utilisant allowedProtectedPackages

L’exemple suivant permet d’utiliser les paquets os et os/exec dans une extension de services :

apis:
  - name: exampleAPI
    serveSE:
      funcName: Serve
      file: /etc/maverics/extensions/serve.go
      allowedProtectedPackages:
        - "os"
        - "os/exec"

/etc/maverics/extensions/serve.go :

package main

import (
    "os"
    "os/exec"

    "github.com/strata-io/service-extension/orchestrator"
)

func Serve(api orchestrator.Orchestrator) error {
    logger := api.Logger()

    // Use the "os" package
    home := os.Getenv("HOME")
	logger.Debug("se", "home directory", "home", home)

    // Use the "os/exec" package
    cmd := exec.Command("ls", "-l")
    cmd.Stdout = os.Stdout
    cmd.Run()
}

Prise en charge de paquets tiers

L’orchestrateur prend en charge un grand nombre de paquets tiers qui peuvent être importés dans les extensions de services. Veuillez consulter la documentation relative aux paquets tiers pour obtenir une liste des bibliothèques pouvant être utilisées.

Les paquets pris en charge peuvent être importés dans les extensions de services en spécifiant le chemin d’importation situé au début du code de l’extension de services.

package main

import (
    ldap "github.com/go-ldap/ldap/v3"
)

Idiomes

Fonctions exportées

Lors de la définition d’une extension de services, le nom de la fonction doit être écrit en majuscules afin d’indiquer que la fonction est exportée et qu’elle sera le point d’entrée appelé par le moteur d’exécution de l’orchestrateur. La mise en majuscule des noms d’extension permet de différencier l’API publique de l’extension de services des utilitaires internes.

Effective Go

Le langage Go définit un large éventail d’idiomes pour l’écriture Effective Go. Les extensions de services devraient généralement se conformer à ces idiomes afin de respecter les bonnes pratiques.