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 }