github.com/redhat-appstudio/e2e-tests@v0.0.0-20240520140907-9709f6f59323/pkg/utils/tekton/pipelineruns.go (about)

     1  package tekton
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"fmt"
     7  	"strconv"
     8  
     9  	"k8s.io/client-go/kubernetes"
    10  	"knative.dev/pkg/apis"
    11  
    12  	"github.com/redhat-appstudio/e2e-tests/pkg/utils"
    13  
    14  	pipeline "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1"
    15  	corev1 "k8s.io/api/core/v1"
    16  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    17  	"k8s.io/apimachinery/pkg/types"
    18  	crclient "sigs.k8s.io/controller-runtime/pkg/client"
    19  )
    20  
    21  const sslCertDir = "/var/run/secrets/kubernetes.io/serviceaccount"
    22  
    23  type PipelineRunGenerator interface {
    24  	Generate() (*pipeline.PipelineRun, error)
    25  }
    26  
    27  type BuildahDemo struct {
    28  	Image     string
    29  	Bundle    string
    30  	Name      string
    31  	Namespace string
    32  }
    33  
    34  type ECIntegrationTestScenario struct {
    35  	Image                 string
    36  	Name                  string
    37  	Namespace             string
    38  	PipelineGitURL        string
    39  	PipelineGitRevision   string
    40  	PipelineGitPathInRepo string
    41  }
    42  
    43  type FailedPipelineRunDetails struct {
    44  	FailedTaskRunName   string
    45  	PodName             string
    46  	FailedContainerName string
    47  }
    48  
    49  // This is a demo pipeline to create test image and task signing
    50  func (b BuildahDemo) Generate() (*pipeline.PipelineRun, error) {
    51  	return &pipeline.PipelineRun{
    52  		ObjectMeta: metav1.ObjectMeta{
    53  			Name:      b.Name,
    54  			Namespace: b.Namespace,
    55  		},
    56  		Spec: pipeline.PipelineRunSpec{
    57  			Params: []pipeline.Param{
    58  				{
    59  					Name:  "dockerfile",
    60  					Value: *pipeline.NewStructuredValues("Containerfile"),
    61  				},
    62  				{
    63  					Name:  "output-image",
    64  					Value: *pipeline.NewStructuredValues(b.Image),
    65  				},
    66  				{
    67  					Name:  "git-url",
    68  					Value: *pipeline.NewStructuredValues("https://github.com/enterprise-contract/golden-container.git"),
    69  				},
    70  				{
    71  					Name:  "skip-checks",
    72  					Value: *pipeline.NewStructuredValues("true"),
    73  				},
    74  			},
    75  			PipelineRef: NewBundleResolverPipelineRef("docker-build", b.Bundle),
    76  			Workspaces: []pipeline.WorkspaceBinding{
    77  				{
    78  					Name: "workspace",
    79  					PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
    80  						ClaimName: "app-studio-default-workspace",
    81  					},
    82  				},
    83  			},
    84  		},
    85  	}, nil
    86  }
    87  
    88  // Generates pipelineRun from VerifyEnterpriseContract.
    89  func (p VerifyEnterpriseContract) Generate() (*pipeline.PipelineRun, error) {
    90  	var applicationSnapshotJSON, err = json.Marshal(p.Snapshot)
    91  	if err != nil {
    92  		return nil, err
    93  	}
    94  	return &pipeline.PipelineRun{
    95  		ObjectMeta: metav1.ObjectMeta{
    96  			GenerateName: fmt.Sprintf("%s-run-", p.Name),
    97  			Namespace:    p.Namespace,
    98  			Labels: map[string]string{
    99  				"appstudio.openshift.io/application": p.Snapshot.Application,
   100  			},
   101  		},
   102  		Spec: pipeline.PipelineRunSpec{
   103  			PipelineSpec: &pipeline.PipelineSpec{
   104  				Tasks: []pipeline.PipelineTask{
   105  					{
   106  						Name: "verify-enterprise-contract",
   107  						Params: []pipeline.Param{
   108  							{
   109  								Name: "IMAGES",
   110  								Value: pipeline.ParamValue{
   111  									Type:      pipeline.ParamTypeString,
   112  									StringVal: string(applicationSnapshotJSON),
   113  								},
   114  							},
   115  							{
   116  								Name: "POLICY_CONFIGURATION",
   117  								Value: pipeline.ParamValue{
   118  									Type:      pipeline.ParamTypeString,
   119  									StringVal: p.PolicyConfiguration,
   120  								},
   121  							},
   122  							{
   123  								Name: "PUBLIC_KEY",
   124  								Value: pipeline.ParamValue{
   125  									Type:      pipeline.ParamTypeString,
   126  									StringVal: p.PublicKey,
   127  								},
   128  							},
   129  							{
   130  								Name: "SSL_CERT_DIR",
   131  								Value: pipeline.ParamValue{
   132  									Type:      pipeline.ParamTypeString,
   133  									StringVal: sslCertDir,
   134  								},
   135  							},
   136  							{
   137  								Name: "STRICT",
   138  								Value: pipeline.ParamValue{
   139  									Type:      pipeline.ParamTypeString,
   140  									StringVal: strconv.FormatBool(p.Strict),
   141  								},
   142  							},
   143  							{
   144  								Name: "EFFECTIVE_TIME",
   145  								Value: pipeline.ParamValue{
   146  									Type:      pipeline.ParamTypeString,
   147  									StringVal: p.EffectiveTime,
   148  								},
   149  							},
   150  							{
   151  								Name: "IGNORE_REKOR",
   152  								Value: pipeline.ParamValue{
   153  									Type:      pipeline.ParamTypeString,
   154  									StringVal: strconv.FormatBool(p.IgnoreRekor),
   155  								},
   156  							},
   157  						},
   158  						TaskRef: &pipeline.TaskRef{
   159  							ResolverRef: pipeline.ResolverRef{
   160  								Resolver: "bundles",
   161  								Params: []pipeline.Param{
   162  									{Name: "name", Value: pipeline.ParamValue{StringVal: "verify-enterprise-contract", Type: pipeline.ParamTypeString}},
   163  									{Name: "bundle", Value: pipeline.ParamValue{StringVal: p.TaskBundle, Type: pipeline.ParamTypeString}},
   164  									{Name: "kind", Value: pipeline.ParamValue{StringVal: "task", Type: pipeline.ParamTypeString}},
   165  								},
   166  							},
   167  						},
   168  					},
   169  				},
   170  			},
   171  		},
   172  	}, nil
   173  }
   174  
   175  // Generates pipelineRun from ECIntegrationTestScenario.
   176  func (p ECIntegrationTestScenario) Generate() (*pipeline.PipelineRun, error) {
   177  
   178  	snapshot := `{"components": [
   179  		{"containerImage": "` + p.Image + `"}
   180  	]}`
   181  
   182  	return &pipeline.PipelineRun{
   183  		ObjectMeta: metav1.ObjectMeta{
   184  			GenerateName: "ec-integration-test-scenario-run-",
   185  			Namespace:    p.Namespace,
   186  		},
   187  		Spec: pipeline.PipelineRunSpec{
   188  			PipelineRef: &pipeline.PipelineRef{
   189  				ResolverRef: pipeline.ResolverRef{
   190  					Resolver: "git",
   191  					Params: []pipeline.Param{
   192  						{Name: "url", Value: *pipeline.NewStructuredValues(p.PipelineGitURL)},
   193  						{Name: "revision", Value: *pipeline.NewStructuredValues(p.PipelineGitRevision)},
   194  						{Name: "pathInRepo", Value: *pipeline.NewStructuredValues(p.PipelineGitPathInRepo)},
   195  					},
   196  				},
   197  			},
   198  			Params: []pipeline.Param{
   199  				{Name: "SNAPSHOT", Value: *pipeline.NewStructuredValues(snapshot)},
   200  			},
   201  		},
   202  	}, nil
   203  }
   204  
   205  // GetFailedPipelineRunLogs gets the logs of the pipelinerun failed task
   206  func GetFailedPipelineRunLogs(c crclient.Client, ki kubernetes.Interface, pipelineRun *pipeline.PipelineRun) (string, error) {
   207  	var d *FailedPipelineRunDetails
   208  	var err error
   209  	failMessage := fmt.Sprintf("Pipelinerun '%s' didn't succeed\n", pipelineRun.Name)
   210  	if d, err = GetFailedPipelineRunDetails(c, pipelineRun); err != nil {
   211  		return "", err
   212  	}
   213  	if d.FailedContainerName != "" {
   214  		logs, _ := utils.GetContainerLogs(ki, d.PodName, d.FailedContainerName, pipelineRun.Namespace)
   215  		failMessage += fmt.Sprintf("Logs from failed container '%s': \n%s", d.FailedContainerName, logs)
   216  	}
   217  	return failMessage, nil
   218  }
   219  
   220  func HasPipelineRunSucceeded(pr *pipeline.PipelineRun) bool {
   221  	return pr.GetStatusCondition().GetCondition(apis.ConditionSucceeded).IsTrue()
   222  }
   223  
   224  func HasPipelineRunFailed(pr *pipeline.PipelineRun) bool {
   225  	return pr.IsDone() && pr.GetStatusCondition().GetCondition(apis.ConditionSucceeded).IsFalse()
   226  }
   227  
   228  func GetFailedPipelineRunDetails(c crclient.Client, pipelineRun *pipeline.PipelineRun) (*FailedPipelineRunDetails, error) {
   229  	d := &FailedPipelineRunDetails{}
   230  	for _, chr := range pipelineRun.Status.PipelineRunStatusFields.ChildReferences {
   231  		taskRun := &pipeline.TaskRun{}
   232  		taskRunKey := types.NamespacedName{Namespace: pipelineRun.Namespace, Name: chr.Name}
   233  		if err := c.Get(context.Background(), taskRunKey, taskRun); err != nil {
   234  			return nil, fmt.Errorf("failed to get details for PR %s: %+v", pipelineRun.GetName(), err)
   235  		}
   236  		for _, c := range taskRun.Status.Conditions {
   237  			if c.Reason == "Failed" {
   238  				d.FailedTaskRunName = taskRun.Name
   239  				d.PodName = taskRun.Status.PodName
   240  				for _, s := range taskRun.Status.TaskRunStatusFields.Steps {
   241  					if s.Terminated.Reason == "Error" {
   242  						d.FailedContainerName = s.Container
   243  						return d, nil
   244  					}
   245  				}
   246  			}
   247  		}
   248  	}
   249  	return d, nil
   250  }