diff --git a/go.mod b/go.mod index 5923a6b..adb36cd 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,8 @@ require ( github.com/docker/docker v27.4.1+incompatible github.com/onsi/ginkgo/v2 v2.22.2 github.com/onsi/gomega v1.36.2 + github.com/pkg/errors v0.9.1 + gopkg.in/yaml.v3 v3.0.1 sigs.k8s.io/controller-runtime v0.19.4 ) @@ -28,7 +30,6 @@ require ( github.com/morikuni/aec v1.0.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0 // indirect - github.com/pkg/errors v0.9.1 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 // indirect go.opentelemetry.io/otel v1.33.0 // indirect @@ -44,6 +45,5 @@ require ( google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect google.golang.org/grpc v1.66.0 // indirect google.golang.org/protobuf v1.36.1 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect gotest.tools/v3 v3.5.1 // indirect ) diff --git a/test/acceptance/ansible_images_test.go b/test/acceptance/ansible_images_test.go new file mode 100644 index 0000000..e50ab69 --- /dev/null +++ b/test/acceptance/ansible_images_test.go @@ -0,0 +1,125 @@ +package acceptance + +import ( + "fmt" + "log" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "github.com/securesign/structural-tests/test/support" +) + +var _ = Describe("Trusted Artifact Signer Ansible", Ordered, func() { + + var ( + snapshotData support.SnapshotData + repositories *support.RepositoryList + + ansibleFileContent []byte + + ansibleTasImages support.AnsibleMap + ansibleOtherImages support.AnsibleMap + ) + + It("get and parse snapshot file", func() { + var err error + snapshotData, err = support.ParseSnapshotData() + support.LogMap(fmt.Sprintf("Snapshot images (%d):", len(snapshotData.Images)), snapshotData.Images) + Expect(err).NotTo(HaveOccurred()) + Expect(snapshotData.Images).NotTo(BeEmpty(), "No images were detected in snapshot file") + + repositories, err = support.LoadRepositoryList() + Expect(err).NotTo(HaveOccurred()) + Expect(repositories.Data).NotTo(BeEmpty(), "No images were detected in repositories file") + }) + + It("load ansible definition file", func() { + var err error + ansibleCollectionURL := support.GetEnv(support.EnvAnsibleImagesFile) + if ansibleCollectionURL == "" { + // standard way - use ansible definition file name from releases snapshot.json + ansibleCollectionURL = snapshotData.Others[support.AnsibleCollectionKey] + Expect(ansibleCollectionURL).NotTo(BeEmpty()) + log.Printf("Using %s URL from snapshot.json file\n", ansibleCollectionURL) + } + ansibleFileContent, err = support.LoadAnsibleCollectionSnapshotFile(ansibleCollectionURL, support.AnsibleCollectionSnapshotFile) + Expect(err).NotTo(HaveOccurred()) + Expect(ansibleFileContent).NotTo(BeEmpty(), "Ansible definition file seems to be empty") + }) + + It("get and parse ansible images definition file", func() { + ansibleAllImages, err := support.MapAnsibleImages(ansibleFileContent) + Expect(err).NotTo(HaveOccurred()) + Expect(ansibleAllImages).NotTo(BeEmpty()) + ansibleTasImages, ansibleOtherImages = support.SplitMap(ansibleAllImages, support.AnsibleTasImageKeys()) + Expect(ansibleTasImages).NotTo(BeEmpty()) + Expect(ansibleOtherImages).NotTo(BeEmpty()) + support.LogMap(fmt.Sprintf("Ansible TAS images (%d):", len(ansibleTasImages)), ansibleTasImages) + support.LogMap(fmt.Sprintf("Ansible other images (%d):", len(ansibleOtherImages)), ansibleOtherImages) + }) + + It("ansible TAS images are listed in registry.redhat.io", func() { + var errs []error + for _, ansibleImage := range ansibleTasImages { + if repositories.FindByImage(ansibleImage) == nil { + errs = append(errs, fmt.Errorf("%w: %s", ErrNotFoundInRegistry, ansibleImage)) + } + } + Expect(errs).To(BeEmpty()) + }) + + It("ansible TAS images are all valid", func() { + Expect(support.GetMapKeys(ansibleTasImages)).To(ContainElements(support.AnsibleTasImageKeys())) + Expect(len(ansibleTasImages)).To(BeNumerically("==", len(support.AnsibleTasImageKeys()))) + Expect(ansibleTasImages).To(HaveEach(MatchRegexp(support.TasImageDefinitionRegexp))) + }) + + It("ansible other images are all valid", func() { + Expect(support.GetMapKeys(ansibleOtherImages)).To(ContainElements(support.AnsibleOtherImageKeys())) + Expect(len(ansibleOtherImages)).To(BeNumerically("==", len(support.AnsibleOtherImageKeys()))) + Expect(ansibleOtherImages).To(HaveEach(MatchRegexp(support.OtherImageDefinitionRegexp))) + }) + + It("all ansible TAS image hashes are also defined in releases snapshot", func() { + mapped := make(map[string]string) + for _, imageKey := range support.AnsibleTasImageKeys() { + + // skip, while ansible uses older tuf image + if imageKey == "tas_single_node_tuf_image" { + log.Printf("Ansible uses differet TUF image - skipping") + log.Printf(" Ansible: %s", ansibleTasImages[imageKey]) + log.Printf(" Snapshot: %s", snapshotData.Images[support.ConvertAnsibleImageKey(imageKey)]) + continue + } + + aSha := support.ExtractHash(ansibleTasImages[imageKey]) + if _, keyExist := snapshotData.Images[support.ConvertAnsibleImageKey(imageKey)]; !keyExist { + mapped[imageKey] = "MISSING" + continue + } + sSha := support.ExtractHash(snapshotData.Images[support.ConvertAnsibleImageKey(imageKey)]) + if aSha == sSha { + mapped[imageKey] = "match" + } else { + mapped[imageKey] = "DIFFERENT HASHES" + } + } + Expect(mapped).To(HaveEach("match"), "Ansible images are missing or have different hashes in snapshot file") + }) + + It("image hashes are all unique", func() { + aImageHashes := support.ExtractHashes(support.GetMapValues(ansibleTasImages)) + hashesCounts := make(map[string]int) + for _, hash := range aImageHashes { + _, exist := hashesCounts[hash] + if exist { + hashesCounts[hash]++ + } else { + hashesCounts[hash] = 1 + } + } + Expect(hashesCounts).To(HaveEach(1)) + Expect(ansibleTasImages).To(HaveLen(len(hashesCounts))) + }) + +}) diff --git a/test/acceptance/client_server_test.go b/test/acceptance/client_server_test.go index 26bc1c2..bc5ffe0 100644 --- a/test/acceptance/client_server_test.go +++ b/test/acceptance/client_server_test.go @@ -30,16 +30,16 @@ const ( var _ = Describe("Client server", Ordered, func() { var clientServerImage string - var snapshotImages support.SnapshotMap + var snapshotData support.SnapshotData var tmpDir string Describe("client-server image", func() { It("snapshot.json", func() { var err error - snapshotImages, err = support.ParseSnapshotImages() + snapshotData, err = support.ParseSnapshotData() Expect(err).NotTo(HaveOccurred()) - clientServerImage = snapshotImages["client-server-image"] + clientServerImage = snapshotData.Images["client-server-image"] Expect(clientServerImage).NotTo(BeEmpty()) }) @@ -68,13 +68,13 @@ var _ = Describe("Client server", Ordered, func() { It("init", func() { switch cli { case "createtree", "updatetree": - image = snapshotImages[cli+"-image"] + image = snapshotData.Images[cli+"-image"] case "tuftool": - image = snapshotImages["tuf-tool-image"] + image = snapshotData.Images["tuf-tool-image"] case "rekor-cli": - image = snapshotImages["rekor-cli-image"] + image = snapshotData.Images["rekor-cli-image"] default: - image = snapshotImages[cli+"-cli-image"] + image = snapshotData.Images[cli+"-cli-image"] } }) diff --git a/test/acceptance/fbc_images_test.go b/test/acceptance/fbc_images_test.go index 0490602..9d93740 100644 --- a/test/acceptance/fbc_images_test.go +++ b/test/acceptance/fbc_images_test.go @@ -25,16 +25,16 @@ var _ = Describe("File-based catalog images", Ordered, func() { var ocps []TableEntry var bundleImage string - snapshotImages, err := support.ParseSnapshotImages() + snapshotData, err := support.ParseSnapshotData() Expect(err).NotTo(HaveOccurred()) - for key, snapshotImage := range snapshotImages { + for key, snapshotImage := range snapshotData.Images { if strings.Index(key, "fbc-") == 0 { ocps = append(ocps, Entry(key, key, snapshotImage)) } } Expect(ocps).NotTo(BeEmpty()) - bundleImage = snapshotImages[support.OperatorBundleImageKey] + bundleImage = snapshotData.Images[support.OperatorBundleImageKey] DescribeTableSubtree("ocp", func(key, fbcImage string) { @@ -77,9 +77,9 @@ var _ = Describe("File-based catalog images", Ordered, func() { }) It("extract bundle-image from snapshot.json", func() { - snapshotImages, err := support.ParseSnapshotImages() + snapshotData, err := support.ParseSnapshotData() Expect(err).NotTo(HaveOccurred()) - Expect(snapshotImages).NotTo(BeEmpty()) + Expect(snapshotData.Images).NotTo(BeEmpty()) }) diff --git a/test/acceptance/operator_images_test.go b/test/acceptance/operator_images_test.go index 000ac64..9b8e33d 100644 --- a/test/acceptance/operator_images_test.go +++ b/test/acceptance/operator_images_test.go @@ -16,27 +16,27 @@ var ErrNotFoundInRegistry = errors.New("not found in registry") var _ = Describe("Trusted Artifact Signer Operator", Ordered, func() { var ( - snapshotImages support.SnapshotMap + snapshotData support.SnapshotData repositories *support.RepositoryList operatorTasImages support.OperatorMap operatorOtherImages support.OperatorMap operator string ) - It("get and parse snapshot.json file", func() { + It("get and parse snapshot file", func() { var err error - snapshotImages, err = support.ParseSnapshotImages() + snapshotData, err = support.ParseSnapshotData() Expect(err).NotTo(HaveOccurred()) - Expect(snapshotImages).NotTo(BeEmpty()) + Expect(snapshotData.Images).NotTo(BeEmpty(), "No images were detected in snapshot file") repositories, err = support.LoadRepositoryList() Expect(err).NotTo(HaveOccurred()) - Expect(snapshotImages).NotTo(BeEmpty()) + Expect(repositories.Data).NotTo(BeEmpty(), "No images were detected in repositories file") }) It("get operator image", func() { - operator = snapshotImages[support.OperatorImageKey] - Expect(operator).NotTo(BeEmpty()) + operator = snapshotData.Images[support.OperatorImageKey] + Expect(operator).NotTo(BeEmpty(), "Operator image not detected in snapshot file") log.Printf("Using %s\n", operator) }) @@ -64,27 +64,31 @@ var _ = Describe("Trusted Artifact Signer Operator", Ordered, func() { It("operator TAS images are all valid", func() { Expect(support.GetMapKeys(operatorTasImages)).To(ContainElements(support.MandatoryTasOperatorImageKeys())) Expect(len(operatorTasImages)).To(BeNumerically("==", len(support.MandatoryTasOperatorImageKeys()))) - Expect(operatorTasImages).To(HaveEach(MatchRegexp(support.OperatorTasImageDefinitionRegexp))) + Expect(operatorTasImages).To(HaveEach(MatchRegexp(support.TasImageDefinitionRegexp))) }) It("operator other images are all valid", func() { Expect(support.GetMapKeys(operatorOtherImages)).To(ContainElements(support.OtherOperatorImageKeys())) Expect(len(operatorOtherImages)).To(BeNumerically("==", len(support.OtherOperatorImageKeys()))) - Expect(operatorOtherImages).To(HaveEach(MatchRegexp(support.OtherOperatorImageDefinitionRegexp))) + Expect(operatorOtherImages).To(HaveEach(MatchRegexp(support.OtherImageDefinitionRegexp))) }) It("all image hashes are also defined in releases snapshot", func() { mapped := make(map[string]string) for _, imageKey := range support.MandatoryTasOperatorImageKeys() { oSha := support.ExtractHash(operatorTasImages[imageKey]) - sSha := support.ExtractHash(snapshotImages[imageKey]) + if _, keyExist := snapshotData.Images[imageKey]; !keyExist { + mapped[imageKey] = "MISSING" + continue + } + sSha := support.ExtractHash(snapshotData.Images[imageKey]) if oSha == sSha { mapped[imageKey] = "match" } else { mapped[imageKey] = "DIFFERENT HASHES" } } - Expect(mapped).To(HaveEach("match")) + Expect(mapped).To(HaveEach("match"), "Operator images are missing or have different hashes in snapshot file") }) It("image hashes are all unique", func() { @@ -103,11 +107,11 @@ var _ = Describe("Trusted Artifact Signer Operator", Ordered, func() { }) It("operator-bundle use the right operator", func() { - fileContent, err := support.RunImage(snapshotImages[support.OperatorBundleImageKey], []string{"cat", support.OperatorBundleClusterServiceVersionFile}) + fileContent, err := support.RunImage(snapshotData.Images[support.OperatorBundleImageKey], []string{"cat", support.OperatorBundleClusterServiceVersionFile}) Expect(err).NotTo(HaveOccurred()) Expect(fileContent).NotTo(BeEmpty()) - operatorHash := support.ExtractHash(snapshotImages[support.OperatorImageKey]) + operatorHash := support.ExtractHash(snapshotData.Images[support.OperatorImageKey]) re := regexp.MustCompile(`(\w+:\s*[\w./-]+operator[\w-]*@sha256:` + operatorHash + `)`) matches := re.FindAllString(fileContent, -1) Expect(matches).NotTo(BeEmpty()) diff --git a/test/acceptance/releases_images_test.go b/test/acceptance/releases_images_test.go index 2a838df..dd37732 100644 --- a/test/acceptance/releases_images_test.go +++ b/test/acceptance/releases_images_test.go @@ -11,23 +11,23 @@ import ( var _ = Describe("Trusted Artifact Signer Releases", Ordered, func() { var ( - snapshotImages support.SnapshotMap + snapshotData support.SnapshotData ) It("snapshot.json file exist and is parseable", func() { var err error - snapshotImages, err = support.ParseSnapshotImages() + snapshotData, err = support.ParseSnapshotData() Expect(err).NotTo(HaveOccurred()) - support.LogMap(fmt.Sprintf("Snapshot images (%d):", len(snapshotImages)), snapshotImages) - Expect(snapshotImages).NotTo(BeEmpty()) + support.LogMap(fmt.Sprintf("Snapshot images (%d):", len(snapshotData.Images)), snapshotData.Images) + Expect(snapshotData.Images).NotTo(BeEmpty(), "No images were detected in snapshot file") }) It("snapshot.json file contains valid images", func() { - Expect(snapshotImages).To(HaveEach(MatchRegexp(support.SnapshotImageDefinitionRegexp))) + Expect(snapshotData.Images).To(HaveEach(MatchRegexp(support.SnapshotImageDefinitionRegexp))) }) It("snapshot.json file image snapshots are all unique", func() { - snapshotHashes := support.ExtractHashes(support.GetMapValues(snapshotImages)) + snapshotHashes := support.ExtractHashes(support.GetMapValues(snapshotData.Images)) mapped := make(map[string]int) for _, hash := range snapshotHashes { _, exist := mapped[hash] @@ -38,6 +38,6 @@ var _ = Describe("Trusted Artifact Signer Releases", Ordered, func() { } } Expect(mapped).To(HaveEach(1)) - Expect(len(snapshotImages)).To(BeNumerically("==", len(mapped))) + Expect(len(snapshotData.Images)).To(BeNumerically("==", len(mapped))) }) }) diff --git a/test/support/acceptance.go b/test/support/acceptance.go index 6009c42..5e4fcaa 100644 --- a/test/support/acceptance.go +++ b/test/support/acceptance.go @@ -5,25 +5,29 @@ import ( "fmt" "regexp" "slices" + "strings" + + "github.com/pkg/errors" + "gopkg.in/yaml.v3" ) type OperatorMap map[string]string -func ParseSnapshotImages() (SnapshotMap, error) { +func ParseSnapshotData() (SnapshotData, error) { snapshotFileName := GetEnv(EnvReleasesSnapshotFile) if snapshotFileName == "" { - return nil, fmt.Errorf("snapshot file name must be set. Use %s env variable for that", EnvReleasesSnapshotFile) + return SnapshotData{}, errors.New(fmt.Sprintf("snapshot file name must be set. Use %s env variable for that", EnvReleasesSnapshotFile)) } content, err := GetFileContent(snapshotFileName) if err != nil { - return nil, err + return SnapshotData{}, err } - var snapshotImages SnapshotMap - err = json.Unmarshal([]byte(content), &snapshotImages) + var snapshotData SnapshotData + err = json.Unmarshal(content, &snapshotData) if err != nil { - return nil, fmt.Errorf("failed to parse snapshot file: %w", err) + return SnapshotData{}, fmt.Errorf("failed to parse snapshot file: %w", err) } - return snapshotImages, nil + return snapshotData, nil } func ParseOperatorImages(helpContent string) (OperatorMap, OperatorMap) { @@ -46,6 +50,23 @@ func ParseOperatorImages(helpContent string) (OperatorMap, OperatorMap) { return operatorTasImages, operatorOtherImages } +func MapAnsibleImages(ansibleDefinitionFileContent []byte) (AnsibleMap, error) { + var ansibleImages AnsibleMap + err := yaml.Unmarshal(ansibleDefinitionFileContent, &ansibleImages) + if err != nil { + return nil, fmt.Errorf("failed to parse ansible images file: %w", err) + } + return ansibleImages, nil +} + +func ConvertAnsibleImageKey(ansibleImageKey string) string { + if !strings.HasPrefix(ansibleImageKey, "tas_single_node_") { + return ansibleImageKey + } + result := strings.ReplaceAll(strings.TrimPrefix(ansibleImageKey, "tas_single_node_"), "_", "-") + return result +} + func ExtractHashes(images []string) []string { result := make([]string, len(images)) for i, image := range images { diff --git a/test/support/ansible_map_type.go b/test/support/ansible_map_type.go new file mode 100644 index 0000000..1a0c502 --- /dev/null +++ b/test/support/ansible_map_type.go @@ -0,0 +1,29 @@ +package support + +import ( + "fmt" + "strings" + + "gopkg.in/yaml.v3" +) + +type AnsibleMap map[string]string + +func (data *AnsibleMap) UnmarshalYAML(value *yaml.Node) error { + *data = make(map[string]string) + + var rawMap map[string]interface{} + if err := value.Decode(&rawMap); err != nil { + return fmt.Errorf("error while parsing yaml file: %w", err) + } + + for key, val := range rawMap { + if strings.HasSuffix(key, "image") { + if strVal, ok := val.(string); ok { + (*data)[key] = strVal + } + } + } + + return nil +} diff --git a/test/support/common.go b/test/support/common.go index 10d058f..9bf58fe 100644 --- a/test/support/common.go +++ b/test/support/common.go @@ -42,6 +42,29 @@ func GetMapValues(m map[string]string) []string { return result } +func SplitMap(original map[string]string, keysToKeep []string) (map[string]string, map[string]string) { + remaining := make(map[string]string) + moved := make(map[string]string) + + for key, value := range original { + if contains(keysToKeep, key) { + remaining[key] = value + } else { + moved[key] = value + } + } + return remaining, moved +} + +func contains(source []string, value string) bool { + for _, v := range source { + if v == value { + return true + } + } + return false +} + func LogArray(message string, data []string) { result := message + "\n" for _, value := range data { @@ -53,7 +76,7 @@ func LogArray(message string, data []string) { func LogMap(message string, data map[string]string) { result := message + "\n" for key, value := range data { - result += fmt.Sprintf(" [%-28s] %s\n", key, value) + result += fmt.Sprintf(" [%-41s] %s\n", key, value) } log.Print(result) } diff --git a/test/support/file_utils.go b/test/support/file_utils.go index 37b614f..c289144 100644 --- a/test/support/file_utils.go +++ b/test/support/file_utils.go @@ -1,6 +1,9 @@ package support import ( + "archive/tar" + "archive/zip" + "bytes" "compress/gzip" "context" "errors" @@ -15,7 +18,7 @@ import ( testroot "github.com/securesign/structural-tests/test" ) -func GetFileContent(filePath string) (string, error) { +func GetFileContent(filePath string) ([]byte, error) { snapshotFile, isLocal := checkFilePath(filePath) if isLocal { return loadFileContent(snapshotFile) @@ -40,11 +43,11 @@ func localPathCleanup(origPath string) string { return filepath.Clean(finalPath) } -func downloadFileContent(url string, accessToken string) (string, error) { +func downloadFileContent(url string, accessToken string) ([]byte, error) { log.Printf("Downloading file %s\n", url) req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, url, nil) if err != nil { - return "", fmt.Errorf("failed to create new request: %w", err) + return nil, fmt.Errorf("failed to create new request: %w", err) } if accessToken != "" { req.Header.Add("Authorization", "token "+accessToken) @@ -52,34 +55,35 @@ func downloadFileContent(url string, accessToken string) (string, error) { client := &http.Client{} resp, err := client.Do(req) if err != nil { - return "", fmt.Errorf("failed to get response: %w", err) + return nil, fmt.Errorf("failed to get response: %w", err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { + log.Printf("Failed to download file: %v", resp) err := errors.New("bad status: " + resp.Status) - return "", err + return nil, err } body, err := io.ReadAll(resp.Body) if err != nil { - return "", fmt.Errorf("failed to read file: %w", err) + return nil, fmt.Errorf("failed to read file: %w", err) } - return string(body), nil + return body, nil } -func loadFileContent(filePath string) (string, error) { +func loadFileContent(filePath string) ([]byte, error) { log.Printf("Loading file %s\n", filePath) file, err := os.Open(filePath) if err != nil { - return "", fmt.Errorf("failed to open file: %w", err) + return nil, fmt.Errorf("failed to open file: %w", err) } defer file.Close() contentBuffer, err := io.ReadAll(file) if err != nil { - return "", fmt.Errorf("failed to read content of the file: %w", err) + return nil, fmt.Errorf("failed to read content of the file: %w", err) } - return string(contentBuffer), nil + return contentBuffer, nil } // DecompressGzipFile decompresses a Gzip file and writes the decompressed content to a specified output file. @@ -112,3 +116,67 @@ func DecompressGzipFile(gzipPath string, outputPath string) error { } return nil } + +func LoadAnsibleCollectionSnapshotFile(zipFileURL, ansibleImagesFile string) ([]byte, error) { + zipData, err := GetFileContent(zipFileURL) + if err != nil { + return nil, err + } + + zipReader, err := zip.NewReader(bytes.NewReader(zipData), int64(len(zipData))) + if err != nil { + return nil, fmt.Errorf("failed to read a zip file: %w", err) + } + + for _, zipFile := range zipReader.File { + log.Printf("Extracted from zip: %s\n", zipFile.Name) + zipFileContent, err := zipFile.Open() + if err != nil { + return nil, fmt.Errorf("failed to open zip file: %w", err) + } + defer zipFileContent.Close() + + gzipReader, err := gzip.NewReader(zipFileContent) + if err != nil { + return nil, fmt.Errorf("failed to gunzip file: %w", err) + } + defer gzipReader.Close() + + log.Printf("Extracted from gzip %s\n", gzipReader.Name) + tarFileContent, err := lookThroughTarFile(gzipReader, ansibleImagesFile) + if err != nil { + return nil, err + } + if tarFileContent != nil { + return tarFileContent, nil + } + } + + return nil, nil +} + +func lookThroughTarFile(reader io.Reader, filePath string) ([]byte, error) { + tarReader := tar.NewReader(reader) + for { + tarHeader, err := tarReader.Next() + if err == io.EOF { + break + } + if err != nil { + return nil, fmt.Errorf("failed to read files from tar file: %w", err) + } + + if tarHeader.Name == filePath { + log.Printf("Found %s\n", tarHeader.Name) + tarFileContent, err := io.ReadAll(tarReader) + if err != nil { + return nil, fmt.Errorf("failed to read from tar file: %w", err) + } + if tarFileContent == nil { + log.Printf("%s not found\n", filePath) + } + return tarFileContent, nil + } + } + return nil, nil +} diff --git a/test/support/image_utils.go b/test/support/image_utils.go index 33bc931..0ac5fe3 100644 --- a/test/support/image_utils.go +++ b/test/support/image_utils.go @@ -23,7 +23,9 @@ func RunImage(imageDefinition string, commands []string) (string, error) { if err != nil { return "", fmt.Errorf("error while initializing docker client: %w", err) } - reader, err := cli.ImagePull(ctx, imageDefinition, image.PullOptions{}) + reader, err := cli.ImagePull(ctx, imageDefinition, image.PullOptions{ + Platform: "linux/amd64", + }) if err != nil { return "", fmt.Errorf("cannot pull image %s: %w", imageDefinition, err) } diff --git a/test/support/repository.go b/test/support/repository.go index 6471ae9..396eaca 100644 --- a/test/support/repository.go +++ b/test/support/repository.go @@ -50,7 +50,7 @@ func LoadRepositoryList() (*RepositoryList, error) { return nil, err } var list RepositoryList - err = json.Unmarshal([]byte(content), &list) + err = json.Unmarshal(content, &list) if err != nil { return nil, fmt.Errorf("failed to parse repositories file: %w", err) } diff --git a/test/support/snapshot_map_type.go b/test/support/snapshot_map_type.go index 89fd1cd..0413162 100644 --- a/test/support/snapshot_map_type.go +++ b/test/support/snapshot_map_type.go @@ -6,29 +6,43 @@ import ( "regexp" ) -type SnapshotMap map[string]string +type SnapshotData struct { + Images map[string]string + Others map[string]string +} var imageRegexp = regexp.MustCompile(`^(fbc-[\w-]+|[\w-]+-image)$`) -func (data *SnapshotMap) UnmarshalJSON(b []byte) error { +func (data *SnapshotData) UnmarshalJSON(b []byte) error { var raw map[string]interface{} if err := json.Unmarshal(b, &raw); err != nil { return fmt.Errorf("error while parsing json file: %w", err) } - *data = make(map[string]string) + *data = SnapshotData{ + make(map[string]string), + make(map[string]string), + } extractImages(raw, *data) return nil } -func extractImages(data map[string]interface{}, images map[string]string) { - for key, value := range data { +func extractImages(rawData map[string]interface{}, snapshotData SnapshotData) { + for key, value := range rawData { switch valueType := value.(type) { case string: if isImageDefinition(key) { - images[key] = valueType + snapshotData.Images[key] = valueType } case map[string]interface{}: - extractImages(valueType, images) + if key == "artifact-signer-ansible" { + if collection, ok := value.(map[string]interface{})["collection"].(map[string]interface{}); ok { + if url, ok := collection["url"].(string); ok { + snapshotData.Others[AnsibleCollectionKey] = url + } + } + } else { + extractImages(valueType, snapshotData) + } } } } diff --git a/test/support/test_constants.go b/test/support/test_constants.go index 433fca2..565e4d5 100644 --- a/test/support/test_constants.go +++ b/test/support/test_constants.go @@ -2,17 +2,20 @@ package support const ( EnvReleasesSnapshotFile = "SNAPSHOT" + EnvAnsibleImagesFile = "ANSIBLE" EnvRepositoriesFile = "REPOSITORIES" EnvTestGithubToken = "TEST_GITHUB_TOKEN" // #nosec G101 OperatorImageKey = "rhtas-operator-image" OperatorBundleImageKey = "rhtas-operator-bundle-image" + AnsibleCollectionKey = "artifact-signer-ansible.collection.url" + AnsibleCollectionSnapshotFile = "roles/tas_single_node/defaults/main.yml" OperatorBundleClusterServiceVersionFile = "manifests/rhtas-operator.clusterserviceversion.yaml" - OperatorTasImageDefinitionRegexp = `^registry.redhat.io/rhtas/[\w/-]+@sha256:\w{64}$` - OtherOperatorImageDefinitionRegexp = `^(registry.redhat.io|registry.access.redhat.com)` - SnapshotImageDefinitionRegexp = `^[\.\w/-]+@sha256:\w{64}$` + TasImageDefinitionRegexp = `^registry.redhat.io/rhtas/[\w/-]+@sha256:\w{64}$` + OtherImageDefinitionRegexp = `^(registry.redhat.io|registry.access.redhat.com)` + SnapshotImageDefinitionRegexp = `^[\.\w/-]+@sha256:\w{64}$` DefaultRepositoriesFile = "testdata/repositories.json" ) @@ -49,6 +52,32 @@ func OtherOperatorImageKeys() []string { } } +func AnsibleTasImageKeys() []string { + return []string{ + "tas_single_node_fulcio_server_image", + "tas_single_node_trillian_log_server_image", + "tas_single_node_trillian_log_signer_image", + "tas_single_node_rekor_server_image", + "tas_single_node_ctlog_image", + "tas_single_node_rekor_redis_image", + "tas_single_node_trillian_db_image", + "tas_single_node_tuf_image", + "tas_single_node_timestamp_authority_image", + "tas_single_node_rekor_search_ui_image", + "tas_single_node_createtree_image", + "tas_single_node_client_server_image", + "tas_single_node_backfill_redis_image", + } +} + +func AnsibleOtherImageKeys() []string { + return []string{ + "tas_single_node_http_server_image", + "tas_single_node_trillian_netcat_image", + "tas_single_node_nginx_image", + } +} + type OSArchMatrix map[string][]string func GetOSArchMatrix() OSArchMatrix {