github.com/redhat-appstudio/e2e-tests@v0.0.0-20240520140907-9709f6f59323/pkg/clients/release/sbom.go (about) 1 /* SBOM of type structures matches Pyxis structure 2 3 When SBOM components are uploaded to Pyxis, key names have to be modified 4 to conform to GraphQL naming conventions. 5 1. Use _ instead of camel case, e.g. camelCase -> camel_case 6 2. Use _ instead of -, e.g. key-with-dash -> key_with_dash 7 See https://github.com/redhat-appstudio/release-service-utils/blob/main/pyxis/upload_sbom.py 8 9 */ 10 11 package release 12 13 import ( 14 "crypto/tls" 15 "fmt" 16 "io" 17 "net/http" 18 "regexp" 19 ) 20 21 // Defines a struct Links with fields for various types of links including artifacts, requests, RPM manifests, 22 // test results, and vulnerabilities. Each field is represented by a corresponding struct type. 23 type Links struct { 24 Artifacts ArtifactLinks `json:"artifacts"` 25 Requests RequestLinks `json:"requests"` 26 RpmManifest RpmManifestLinks `json:"rpm_manifest"` 27 TestResults TestResultsLinks `json:"test_results"` 28 Vulnerabilities VulnerabilitiesLinks `json:"vulnerabilities"` 29 } 30 31 // Defines a struct ArtifactLinks with a single field Href for storing a link related to an artifact. 32 type ArtifactLinks struct { 33 Href string `json:"href"` 34 } 35 36 // Defines a struct RequestLinks with a single field Href for storing a link related to a request. 37 type RequestLinks struct { 38 Href string `json:"href"` 39 } 40 41 // Defines a struct RpmManifestLinks with a single field Href for storing a link to an RPM manifest. 42 type RpmManifestLinks struct { 43 Href string `json:"href"` 44 } 45 46 // Defines a struct TestResultsLinks with a single field Href for storing a link to test results. 47 type TestResultsLinks struct { 48 Href string `json:"href"` 49 } 50 51 // Defines a struct VulnerabilitiesLinks with a single field Href for storing a link. 52 type VulnerabilitiesLinks struct { 53 Href string `json:"href"` 54 } 55 56 // ContentManifest id of content manifest 57 type ContentManifest struct { 58 ID string `json:"_id"` 59 } 60 61 // Defines a struct FreshnessGrade with fields for creation date, grade, and start date. 62 type FreshnessGrade struct { 63 CreationDate string `json:"creation_date"` 64 Grade string `json:"grade"` 65 StartDate string `json:"start_date"` 66 } 67 68 // ParsedData general details of env 69 type ParsedData struct { 70 Architecture string `json:"architecture"` 71 DockerVersion string `json:"docker_version"` 72 EnvVariables []string `json:"env_variables"` 73 } 74 75 // Defines a struct Image with various fields representing image properties and metadata. 76 // It includes fields for ID, links, architecture, certification status, content manifest, 77 // content manifest components, creator information, creation date, Docker image digest, 78 // freshness grades, image ID, last update date, last updated by, object type, and parsed data. 79 type Image struct { 80 ID string `json:"_id"` 81 Links Links `json:"_links"` 82 Architecture string `json:"architecture"` 83 Certified bool `json:"certified"` 84 ContentManifest ContentManifest `json:"content_manifest"` 85 CreatedBy string `json:"created_by"` 86 CreatedOnBehalfOf interface{} `json:"created_on_behalf_of"` 87 CreationDate string `json:"creation_date"` 88 DockerImageDigest string `json:"docker_image_digest"` 89 FreshnessGrades []FreshnessGrade `json:"freshness_grades"` 90 ImageID string `json:"image_id"` 91 LastUpdateDate string `json:"last_update_date"` 92 LastUpdatedBy string `json:"last_updated_by"` 93 ObjectType string `json:"object_type"` 94 ParsedData ParsedData `json:"parsed_data"` 95 } 96 97 // GetPyxisImageByImageID makes a GET request to stage Pyxis to get an image 98 // and returns it. 99 func (r *ReleaseController) GetPyxisImageByImageID(pyxisStageImagesApiEndpoint, imageID string, 100 pyxisCertDecoded, pyxisKeyDecoded []byte) ([]byte, error) { 101 102 url := fmt.Sprintf("%s%s", pyxisStageImagesApiEndpoint, imageID) 103 104 // Create a TLS configuration with the key and certificate 105 cert, err := tls.X509KeyPair(pyxisCertDecoded, pyxisKeyDecoded) 106 if err != nil { 107 return nil, fmt.Errorf("error creating TLS certificate and key: %s", err) 108 } 109 110 // Create a client with the custom TLS configuration 111 client := &http.Client{ 112 Transport: &http.Transport{ 113 TLSClientConfig: &tls.Config{ 114 Certificates: []tls.Certificate{cert}, 115 }, 116 }, 117 } 118 119 // Send GET request 120 request, err := http.NewRequest("GET", url, nil) 121 if err != nil { 122 return nil, fmt.Errorf("error creating GET request: %s", err) 123 } 124 125 response, err := client.Do(request) 126 if err != nil { 127 return nil, fmt.Errorf("error sending GET request: %s", err) 128 } 129 130 defer response.Body.Close() 131 132 // Read the response body 133 body, err := io.ReadAll(response.Body) 134 if err != nil { 135 return nil, fmt.Errorf("error reading response body: %s", err) 136 } 137 return body, nil 138 } 139 140 // GetPyxisImageIDsFromCreatePyxisImageTaskLogs takes a slice of task logs (as this is what 141 // TektonController.GetTaskRunLogs returns) and parses them for the imageIDs, returning them 142 // as a slice. 143 func (r *ReleaseController) GetPyxisImageIDsFromCreatePyxisImageTaskLogs(logs map[string]string) ([]string, error) { 144 var imageIDs []string 145 146 re := regexp.MustCompile(`(?:The image id is: )(.+)`) 147 148 for _, tasklog := range logs { 149 for _, matchingString := range re.FindAllString(tasklog, -1) { 150 imageIDs = append(imageIDs, re.FindStringSubmatch(matchingString)[1]) 151 } 152 } 153 154 return imageIDs, nil 155 }