github.com/redhat-appstudio/e2e-tests@v0.0.0-20230619105049-9a422b2094d7/pkg/utils/tekton/pipelines.go (about)

     1  package tekton
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"os"
     7  	"strconv"
     8  
     9  	. "github.com/onsi/ginkgo/v2"
    10  
    11  	app "github.com/redhat-appstudio/application-api/api/v1alpha1"
    12  	"github.com/redhat-appstudio/e2e-tests/pkg/utils"
    13  	"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"
    14  	corev1 "k8s.io/api/core/v1"
    15  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    16  	"k8s.io/client-go/kubernetes"
    17  	crclient "sigs.k8s.io/controller-runtime/pkg/client"
    18  	"sigs.k8s.io/yaml"
    19  )
    20  
    21  type PipelineRunGenerator interface {
    22  	Generate() *v1beta1.PipelineRun
    23  }
    24  
    25  type BuildahDemo struct {
    26  	Image     string
    27  	Bundle    string
    28  	Name      string
    29  	Namespace string
    30  }
    31  
    32  // This is a demo pipeline to create test image and task signing
    33  func (g BuildahDemo) Generate() *v1beta1.PipelineRun {
    34  
    35  	return &v1beta1.PipelineRun{
    36  		ObjectMeta: metav1.ObjectMeta{
    37  			Name:      g.Name,
    38  			Namespace: g.Namespace,
    39  		},
    40  		Spec: v1beta1.PipelineRunSpec{
    41  			Params: []v1beta1.Param{
    42  				{
    43  					Name:  "dockerfile",
    44  					Value: *v1beta1.NewArrayOrString("Dockerfile"),
    45  				},
    46  				{
    47  					Name:  "output-image",
    48  					Value: *v1beta1.NewArrayOrString(g.Image),
    49  				},
    50  				{
    51  					Name:  "git-url",
    52  					Value: *v1beta1.NewArrayOrString("https://github.com/ziwoshixianzhe/simple_docker_app.git"),
    53  				},
    54  				{
    55  					Name:  "skip-checks",
    56  					Value: *v1beta1.NewArrayOrString("true"),
    57  				},
    58  			},
    59  			PipelineRef: &v1beta1.PipelineRef{
    60  				Name:   "docker-build",
    61  				Bundle: g.Bundle,
    62  			},
    63  			Workspaces: []v1beta1.WorkspaceBinding{
    64  				{
    65  					Name: "workspace",
    66  					PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
    67  						ClaimName: "app-studio-default-workspace",
    68  					},
    69  				},
    70  			},
    71  		},
    72  	}
    73  }
    74  
    75  type VerifyEnterpriseContract struct {
    76  	ApplicationName     string
    77  	Bundle              string
    78  	ComponentName       string
    79  	Image               string
    80  	Name                string
    81  	Namespace           string
    82  	PolicyConfiguration string
    83  	PublicKey           string
    84  	SSLCertDir          string
    85  	Strict              bool
    86  	EffectiveTime       string
    87  }
    88  
    89  func (p VerifyEnterpriseContract) Generate() *v1beta1.PipelineRun {
    90  	var snapshot app.SnapshotSpec
    91  	err := json.Unmarshal([]byte(p.Image), &snapshot)
    92  	if err != nil {
    93  		fmt.Printf("Application Snapshot doesn't exist: %s\n", err)
    94  	}
    95  
    96  	if len(snapshot.Components) == 0 {
    97  		p.Image = `{
    98  			"application": "` + p.ApplicationName + `",
    99  			"components": [
   100  			  {
   101  				"name": "` + p.ComponentName + `",
   102  				"containerImage": "` + p.Image + `"
   103  			  }
   104  			]
   105  		  }`
   106  	}
   107  	return &v1beta1.PipelineRun{
   108  		ObjectMeta: metav1.ObjectMeta{
   109  			GenerateName: fmt.Sprintf("%s-run-", p.Name),
   110  			Namespace:    p.Namespace,
   111  			Labels: map[string]string{
   112  				"appstudio.openshift.io/application": p.ApplicationName,
   113  				"appstudio.openshift.io/component":   p.ComponentName,
   114  			},
   115  		},
   116  		Spec: v1beta1.PipelineRunSpec{
   117  			PipelineSpec: &v1beta1.PipelineSpec{
   118  				Tasks: []v1beta1.PipelineTask{
   119  					{
   120  						Name: "verify-enterprise-contract",
   121  						Params: []v1beta1.Param{
   122  							{
   123  								Name: "IMAGES",
   124  								Value: v1beta1.ArrayOrString{
   125  									Type:      v1beta1.ParamTypeString,
   126  									StringVal: p.Image,
   127  								},
   128  							},
   129  							{
   130  								Name: "POLICY_CONFIGURATION",
   131  								Value: v1beta1.ArrayOrString{
   132  									Type:      v1beta1.ParamTypeString,
   133  									StringVal: p.PolicyConfiguration,
   134  								},
   135  							},
   136  							{
   137  								Name: "PUBLIC_KEY",
   138  								Value: v1beta1.ArrayOrString{
   139  									Type:      v1beta1.ParamTypeString,
   140  									StringVal: p.PublicKey,
   141  								},
   142  							},
   143  							{
   144  								Name: "SSL_CERT_DIR",
   145  								Value: v1beta1.ArrayOrString{
   146  									Type:      v1beta1.ParamTypeString,
   147  									StringVal: p.SSLCertDir,
   148  								},
   149  							},
   150  							{
   151  								Name: "STRICT",
   152  								Value: v1beta1.ArrayOrString{
   153  									Type:      v1beta1.ParamTypeString,
   154  									StringVal: strconv.FormatBool(p.Strict),
   155  								},
   156  							},
   157  							{
   158  								Name: "EFFECTIVE_TIME",
   159  								Value: v1beta1.ArrayOrString{
   160  									Type:      v1beta1.ParamTypeString,
   161  									StringVal: p.EffectiveTime,
   162  								},
   163  							},
   164  						},
   165  						TaskRef: &v1beta1.TaskRef{
   166  							Name:   "verify-enterprise-contract",
   167  							Bundle: p.Bundle,
   168  						},
   169  					},
   170  				},
   171  			},
   172  		},
   173  	}
   174  }
   175  
   176  // GetFailedPipelineRunLogs gets the logs of the pipelinerun failed task
   177  func GetFailedPipelineRunLogs(c crclient.Client, ki kubernetes.Interface, pipelineRun *v1beta1.PipelineRun) (string, error) {
   178  	var d *utils.FailedPipelineRunDetails
   179  	var err error
   180  	failMessage := fmt.Sprintf("Pipelinerun '%s' didn't succeed\n", pipelineRun.Name)
   181  	if d, err = utils.GetFailedPipelineRunDetails(c, pipelineRun); err != nil {
   182  		return "", err
   183  	}
   184  	if d.FailedContainerName != "" {
   185  		logs, _ := utils.GetContainerLogs(ki, d.PodName, d.FailedContainerName, pipelineRun.Namespace)
   186  		failMessage += fmt.Sprintf("Logs from failed container '%s': \n%s", d.FailedContainerName, logs)
   187  	}
   188  	return failMessage, nil
   189  }
   190  
   191  // StorePipelineRunLogs stores logs and parsed yamls of pipelineRuns into directory of pipelineruns' namespace under ARTIFACT_DIR env.
   192  // In case the files can't be stored in ARTIFACT_DIR, they will be recorder in GinkgoWriter.
   193  func StorePipelineRun(pipelineRun *v1beta1.PipelineRun, c crclient.Client, ki kubernetes.Interface) error {
   194  	wd, _ := os.Getwd()
   195  	artifactDir := utils.GetEnv("ARTIFACT_DIR", fmt.Sprintf("%s/tmp", wd))
   196  	testLogsDir := fmt.Sprintf("%s/%s", artifactDir, pipelineRun.GetNamespace())
   197  
   198  	pipelineRunLog, err := GetFailedPipelineRunLogs(c, ki, pipelineRun)
   199  	if err != nil {
   200  		return fmt.Errorf("failed to store PipelineRun: %+v", err)
   201  	}
   202  
   203  	pipelineRunYaml, prYamlErr := yaml.Marshal(pipelineRun)
   204  	if prYamlErr != nil {
   205  		GinkgoWriter.Printf("\nfailed to get pipelineRunYaml: %s\n", prYamlErr.Error())
   206  	}
   207  
   208  	err = os.MkdirAll(testLogsDir, os.ModePerm)
   209  
   210  	if err != nil {
   211  		GinkgoWriter.Printf("\n%s\nFailed pipelineRunLog:\n%s\n---END OF THE LOG---\n", pipelineRun.GetName(), pipelineRunLog)
   212  		if prYamlErr == nil {
   213  			GinkgoWriter.Printf("Failed pipelineRunYaml:\n%s\n", pipelineRunYaml)
   214  		}
   215  		return err
   216  	}
   217  
   218  	filename := fmt.Sprintf("%s-pr-%s.log", pipelineRun.Namespace, pipelineRun.Name)
   219  	filePath := fmt.Sprintf("%s/%s", testLogsDir, filename)
   220  	if err := os.WriteFile(filePath, []byte(pipelineRunLog), 0644); err != nil {
   221  		GinkgoWriter.Printf("cannot write to %s: %+v\n", filename, err)
   222  		GinkgoWriter.Printf("\n%s\nFailed pipelineRunLog:\n%s\n", filename, pipelineRunLog)
   223  	}
   224  
   225  	if prYamlErr == nil {
   226  		filename = fmt.Sprintf("%s-pr-%s.yaml", pipelineRun.Namespace, pipelineRun.Name)
   227  		filePath = fmt.Sprintf("%s/%s", testLogsDir, filename)
   228  		if err := os.WriteFile(filePath, pipelineRunYaml, 0644); err != nil {
   229  			GinkgoWriter.Printf("cannot write to %s: %+v\n", filename, err)
   230  			GinkgoWriter.Printf("\n%s\nFailed pipelineRunYaml:\n%s\n", filename, pipelineRunYaml)
   231  		}
   232  	}
   233  
   234  	return nil
   235  }