5.10. Valider les opérateurs à l'aide de la carte de score


En tant qu'auteur de l'opérateur, vous pouvez utiliser l'outil de scorecard dans le SDK de l'opérateur pour effectuer les tâches suivantes :

  • Validez que votre projet Operator ne contient pas d'erreurs de syntaxe et qu'il est correctement empaqueté
  • Examinez les suggestions d'amélioration de votre opérateur

5.10.1. A propos de l'outil carte de score

Alors que la sous-commande Operator SDK bundle validate peut valider le contenu et la structure des répertoires de bundle locaux et des images de bundle distantes, vous pouvez utiliser la commande scorecard pour exécuter des tests sur votre Operator sur la base d'un fichier de configuration et d'images de test. Ces tests sont mis en œuvre dans des images de test qui sont configurées et construites pour être exécutées par le scorecard.

Le scorecard suppose qu'il est exécuté avec un accès à un cluster Kubernetes configuré, tel que OpenShift Container Platform. Le scorecard exécute chaque test dans un pod, à partir duquel les journaux du pod sont agrégés et les résultats des tests sont envoyés à la console. Le scorecard intègre des tests de base et des tests OLM (Operator Lifecycle Manager) et fournit également un moyen d'exécuter des définitions de test personnalisées.

Flux de travail du tableau de bord

  1. Créer toutes les ressources requises par les ressources personnalisées (RC) et l'opérateur
  2. Créer un conteneur proxy dans le déploiement de l'opérateur pour enregistrer les appels au serveur API et exécuter les tests
  3. Examiner les paramètres dans les CR

Les tests du tableau de bord ne font aucune supposition quant à l'état de l'opérateur testé. La création d'opérateurs et de CR pour un opérateur dépasse le champ d'application du tableau de bord lui-même. Les tests du tableau de bord peuvent toutefois créer toutes les ressources dont ils ont besoin si les tests sont conçus pour la création de ressources.

scorecard syntaxe de la commande

$ operator-sdk scorecard <bundle_dir_ou_image> [flags] (drapeaux)

Le tableau de bord requiert un argument de position pour le chemin d'accès au disque de votre groupe d'opérateurs ou le nom d'une image de groupe.

Pour plus d'informations sur les drapeaux, cliquez ici :

$ operator-sdk scorecard -h

5.10.2. Configuration du tableau de bord

L'outil scorecard utilise une configuration qui vous permet de configurer des plugins internes, ainsi que plusieurs options de configuration globales. Les tests sont pilotés par un fichier de configuration nommé config.yaml, qui est généré par la commande make bundle, située dans votre répertoire bundle/:

./bundle
...
└── tests
    └── scorecard
        └── config.yaml

Exemple de fichier de configuration d'un scorecard

kind: Configuration
apiversion: scorecard.operatorframework.io/v1alpha3
metadata:
  name: config
stages:
- parallel: true
  tests:
  - image: quay.io/operator-framework/scorecard-test:v1.25.4
    entrypoint:
    - scorecard-test
    - basic-check-spec
    labels:
      suite: basic
      test: basic-check-spec-test
  - image: quay.io/operator-framework/scorecard-test:v1.25.4
    entrypoint:
    - scorecard-test
    - olm-bundle-validation
    labels:
      suite: olm
      test: olm-bundle-validation-test

Le fichier de configuration définit chaque test que le scorecard peut exécuter. Les champs suivants du fichier de configuration du scorecard définissent le test comme suit :

Champ de configurationDescription

image

Nom de l'image du conteneur de test qui met en œuvre un test

entrypoint

Commande et arguments invoqués dans l'image de test pour exécuter un test

labels

Étiquettes personnalisées ou définies dans le tableau de bord permettant de sélectionner les tests à effectuer

5.10.3. Tests de cartes de pointage intégrés

Le tableau de bord est livré avec des tests prédéfinis qui sont organisés en suites : la suite de tests de base et la suite Operator Lifecycle Manager (OLM).

Tableau 5.16. Suite de tests de base
TestDescriptionNom court

Existence d'un bloc de spécifications

Ce test vérifie que toutes les ressources personnalisées (CR) créées dans le cluster disposent d'un bloc spec.

basic-check-spec-test

Tableau 5.17. Suite de tests OLM
TestDescriptionNom court

Validation de l'offre groupée

Ce test valide les manifestes de la liasse trouvés dans la liasse qui est passée dans le scorecard. Si le contenu de la liasse contient des erreurs, le résultat du test comprend le journal du validateur ainsi que les messages d'erreur de la bibliothèque de validation.

olm-bundle-validation-test

Les API fournies sont validées

Ce test permet de vérifier que les définitions de ressources personnalisées (CRD) pour les CR fournis contiennent une section de validation et qu'il existe une validation pour chaque champ spec et status détecté dans le CR.

olm-crds-have-validation-test

Les CRD possédés ont des ressources répertoriées

Ce test vérifie que les CRD de chaque CR fourni via l'option cr-manifest ont une sous-section resources dans la section owned CRDs du ClusterServiceVersion (CSV). Si le test détecte des ressources utilisées qui ne sont pas répertoriées dans la section des ressources, il les énumère dans les suggestions à la fin du test. Les utilisateurs doivent remplir la section des ressources après la génération initiale du code pour que ce test soit réussi.

olm-crds-have-resources-test

Champs spécifiques avec descripteurs

Ce test permet de vérifier que chaque champ des sections CRs spec a un descripteur correspondant répertorié dans le CSV.

olm-spec-descriptors-test

Champs d'état avec descripteurs

Ce test permet de vérifier que chaque champ des sections CRs status a un descripteur correspondant répertorié dans le CSV.

olm-status-descriptors-test

5.10.4. Exécution de l'outil de tableau de bord

Un ensemble de fichiers Kustomize par défaut est généré par le SDK de l'opérateur après l'exécution de la commande init. Le fichier par défaut bundle/tests/scorecard/config.yaml qui est généré peut être immédiatement utilisé pour exécuter l'outil de scorecard avec votre opérateur, ou vous pouvez modifier ce fichier selon les spécifications de votre test.

Conditions préalables

  • Projet d'opérateur généré à l'aide de l'Operator SDK

Procédure

  1. Générer ou régénérer les manifestes et les métadonnées de vos bundles pour votre opérateur :

    $ make bundle

    Cette commande ajoute automatiquement des annotations de scorecard aux métadonnées de votre bundle, qui sont utilisées par la commande scorecard pour exécuter les tests.

  2. Exécutez le tableau de bord en fonction du chemin d'accès au disque de votre groupe d'opérateurs ou du nom d'une image de groupe :

    $ operator-sdk scorecard <bundle_dir_or_image>

5.10.5. Résultats du tableau de bord

L'option --output de la commande scorecard spécifie le format de sortie des résultats de la carte de score : text ou json.

Exemple 5.15. Exemple d'extrait de sortie JSON

{
  "apiVersion": "scorecard.operatorframework.io/v1alpha3",
  "kind": "TestList",
  "items": [
    {
      "kind": "Test",
      "apiVersion": "scorecard.operatorframework.io/v1alpha3",
      "spec": {
        "image": "quay.io/operator-framework/scorecard-test:v1.25.4",
        "entrypoint": [
          "scorecard-test",
          "olm-bundle-validation"
        ],
        "labels": {
          "suite": "olm",
          "test": "olm-bundle-validation-test"
        }
      },
      "status": {
        "results": [
          {
            "name": "olm-bundle-validation",
            "log": "time=\"2020-06-10T19:02:49Z\" level=debug msg=\"Found manifests directory\" name=bundle-test\ntime=\"2020-06-10T19:02:49Z\" level=debug msg=\"Found metadata directory\" name=bundle-test\ntime=\"2020-06-10T19:02:49Z\" level=debug msg=\"Getting mediaType info from manifests directory\" name=bundle-test\ntime=\"2020-06-10T19:02:49Z\" level=info msg=\"Found annotations file\" name=bundle-test\ntime=\"2020-06-10T19:02:49Z\" level=info msg=\"Could not find optional dependencies file\" name=bundle-test\n",
            "state": "pass"
          }
        ]
      }
    }
  ]
}

Exemple 5.16. Exemple d'extrait de texte

--------------------------------------------------------------------------------
Image:      quay.io/operator-framework/scorecard-test:v1.25.4
Entrypoint: [scorecard-test olm-bundle-validation]
Labels:
	"suite":"olm"
	"test":"olm-bundle-validation-test"
Results:
	Name: olm-bundle-validation
	State: pass
	Log:
		time="2020-07-15T03:19:02Z" level=debug msg="Found manifests directory" name=bundle-test
		time="2020-07-15T03:19:02Z" level=debug msg="Found metadata directory" name=bundle-test
		time="2020-07-15T03:19:02Z" level=debug msg="Getting mediaType info from manifests directory" name=bundle-test
		time="2020-07-15T03:19:02Z" level=info msg="Found annotations file" name=bundle-test
		time="2020-07-15T03:19:02Z" level=info msg="Could not find optional dependencies file" name=bundle-test
Note

La spécification du format de sortie correspond à la présentation du type Test de la présentation du type.

5.10.6. Sélection des tests

Les tests du tableau de bord sont sélectionnés en associant l'indicateur CLI --selector à un ensemble de chaînes d'étiquettes. Si aucun drapeau de sélection n'est fourni, tous les tests contenus dans le fichier de configuration du tableau de bord sont exécutés.

Les tests sont exécutés en série, les résultats étant agrégés par le tableau de bord et écrits sur la sortie standard, ou stdout.

Procédure

  1. Pour sélectionner un seul test, par exemple basic-check-spec-test, spécifiez le test en utilisant l'indicateur --selector:

    $ operator-sdk scorecard <bundle_dir_or_image> \
        -o text \
        --selector=test=basic-check-spec-test
  2. Pour sélectionner une série de tests, par exemple olm, indiquez une étiquette utilisée par tous les tests OLM :

    $ operator-sdk scorecard <bundle_dir_or_image> \
        -o text \
        --selector=suite=olm
  3. Pour sélectionner plusieurs tests, spécifiez les noms des tests à l'aide de l'indicateur selector en utilisant la syntaxe suivante :

    $ operator-sdk scorecard <bundle_dir_or_image> \
        -o text \
        --selector='test in (basic-check-spec-test,olm-bundle-validation-test)'

5.10.7. Permettre des tests en parallèle

En tant qu'auteur d'un opérateur, vous pouvez définir des étapes distinctes pour vos tests à l'aide du fichier de configuration du tableau de bord. Les étapes s'exécutent séquentiellement dans l'ordre où elles sont définies dans le fichier de configuration. Une étape contient une liste de tests et un paramètre configurable parallel.

Par défaut, ou lorsqu'une étape définit explicitement parallel à false, les tests d'une étape sont exécutés séquentiellement dans l'ordre où ils sont définis dans le fichier de configuration. L'exécution des tests un par un est utile pour garantir que deux tests n'interagissent pas et n'entrent pas en conflit l'un avec l'autre.

Toutefois, si les tests sont conçus pour être totalement isolés, ils peuvent être parallélisés.

Procédure

  • Pour exécuter un ensemble de tests isolés en parallèle, incluez-les dans la même étape et fixez parallel à true:

    apiVersion: scorecard.operatorframework.io/v1alpha3
    kind: Configuration
    metadata:
      name: config
    stages:
    - parallel: true 1
      tests:
      - entrypoint:
        - scorecard-test
        - basic-check-spec
        image: quay.io/operator-framework/scorecard-test:v1.25.4
        labels:
          suite: basic
          test: basic-check-spec-test
      - entrypoint:
        - scorecard-test
        - olm-bundle-validation
        image: quay.io/operator-framework/scorecard-test:v1.25.4
        labels:
          suite: olm
          test: olm-bundle-validation-test
    1
    Permet de réaliser des tests en parallèle

    Tous les tests d'une étape parallèle sont exécutés simultanément, et Scorecard attend qu'ils soient tous terminés avant de passer à l'étape suivante. Vos tests peuvent ainsi s'exécuter beaucoup plus rapidement.

5.10.8. Tests personnalisés des cartes de pointage

L'outil de tableau de bord peut exécuter des tests personnalisés qui respectent ces conventions obligatoires :

  • Les tests sont mis en œuvre dans une image conteneur
  • Les tests acceptent un point d'entrée comprenant une commande et des arguments
  • Les tests produisent la carte de score v1alpha3 au format JSON, sans journalisation superflue dans la sortie du test
  • Les tests peuvent obtenir le contenu du paquet à un point de montage partagé de /bundle
  • Les tests peuvent accéder à l'API Kubernetes à l'aide d'une connexion client dans le cluster

Il est possible d'écrire des tests personnalisés dans d'autres langages de programmation si l'image de test suit les lignes directrices ci-dessus.

L'exemple suivant montre une image de test personnalisée écrite en Go :

Exemple 5.17. Exemple de test de scorecard personnalisé

// Copyright 2020 The Operator-SDK Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"encoding/json"
	"fmt"
	"log"
	"os"

	scapiv1alpha3 "github.com/operator-framework/api/pkg/apis/scorecard/v1alpha3"
	apimanifests "github.com/operator-framework/api/pkg/manifests"
)

// This is the custom scorecard test example binary
// As with the Redhat scorecard test image, the bundle that is under
// test is expected to be mounted so that tests can inspect the
// bundle contents as part of their test implementations.
// The actual test is to be run is named and that name is passed
// as an argument to this binary.  This argument mechanism allows
// this binary to run various tests all from within a single
// test image.

const PodBundleRoot = "/bundle"

func main() {
	entrypoint := os.Args[1:]
	if len(entrypoint) == 0 {
		log.Fatal("Test name argument is required")
	}

	// Read the pod's untar'd bundle from a well-known path.
	cfg, err := apimanifests.GetBundleFromDir(PodBundleRoot)
	if err != nil {
		log.Fatal(err.Error())
	}

	var result scapiv1alpha3.TestStatus

	// Names of the custom tests which would be passed in the
	// `operator-sdk` command.
	switch entrypoint[0] {
	case CustomTest1Name:
		result = CustomTest1(cfg)
	case CustomTest2Name:
		result = CustomTest2(cfg)
	default:
		result = printValidTests()
	}

	// Convert scapiv1alpha3.TestResult to json.
	prettyJSON, err := json.MarshalIndent(result, "", "    ")
	if err != nil {
		log.Fatal("Failed to generate json", err)
	}
	fmt.Printf("%s\n", string(prettyJSON))

}

// printValidTests will print out full list of test names to give a hint to the end user on what the valid tests are.
func printValidTests() scapiv1alpha3.TestStatus {
	result := scapiv1alpha3.TestResult{}
	result.State = scapiv1alpha3.FailState
	result.Errors = make([]string, 0)
	result.Suggestions = make([]string, 0)

	str := fmt.Sprintf("Valid tests for this image include: %s %s",
		CustomTest1Name,
		CustomTest2Name)
	result.Errors = append(result.Errors, str)
	return scapiv1alpha3.TestStatus{
		Results: []scapiv1alpha3.TestResult{result},
	}
}

const (
	CustomTest1Name = "customtest1"
	CustomTest2Name = "customtest2"
)

// Define any operator specific custom tests here.
// CustomTest1 and CustomTest2 are example test functions. Relevant operator specific
// test logic is to be implemented in similarly.

func CustomTest1(bundle *apimanifests.Bundle) scapiv1alpha3.TestStatus {
	r := scapiv1alpha3.TestResult{}
	r.Name = CustomTest1Name
	r.State = scapiv1alpha3.PassState
	r.Errors = make([]string, 0)
	r.Suggestions = make([]string, 0)
	almExamples := bundle.CSV.GetAnnotations()["alm-examples"]
	if almExamples == "" {
		fmt.Println("no alm-examples in the bundle CSV")
	}

	return wrapResult(r)
}

func CustomTest2(bundle *apimanifests.Bundle) scapiv1alpha3.TestStatus {
	r := scapiv1alpha3.TestResult{}
	r.Name = CustomTest2Name
	r.State = scapiv1alpha3.PassState
	r.Errors = make([]string, 0)
	r.Suggestions = make([]string, 0)
	almExamples := bundle.CSV.GetAnnotations()["alm-examples"]
	if almExamples == "" {
		fmt.Println("no alm-examples in the bundle CSV")
	}
	return wrapResult(r)
}

func wrapResult(r scapiv1alpha3.TestResult) scapiv1alpha3.TestStatus {
	return scapiv1alpha3.TestStatus{
		Results: []scapiv1alpha3.TestResult{r},
	}
}
Red Hat logoGithubRedditYoutubeTwitter

Apprendre

Essayez, achetez et vendez

Communautés

À propos de la documentation Red Hat

Nous aidons les utilisateurs de Red Hat à innover et à atteindre leurs objectifs grâce à nos produits et services avec un contenu auquel ils peuvent faire confiance.

Rendre l’open source plus inclusif

Red Hat s'engage à remplacer le langage problématique dans notre code, notre documentation et nos propriétés Web. Pour plus de détails, consultez leBlog Red Hat.

À propos de Red Hat

Nous proposons des solutions renforcées qui facilitent le travail des entreprises sur plusieurs plates-formes et environnements, du centre de données central à la périphérie du réseau.

© 2024 Red Hat, Inc.