release/cli/pkg/bundles/package-controller.go (194 lines of code) (raw):

// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bundles import ( "fmt" "strings" "github.com/pkg/errors" anywherev1alpha1 "github.com/aws/eks-anywhere/release/api/v1alpha1" "github.com/aws/eks-anywhere/release/cli/pkg/aws/ecr" "github.com/aws/eks-anywhere/release/cli/pkg/aws/ecrpublic" "github.com/aws/eks-anywhere/release/cli/pkg/constants" "github.com/aws/eks-anywhere/release/cli/pkg/helm" "github.com/aws/eks-anywhere/release/cli/pkg/images" releasetypes "github.com/aws/eks-anywhere/release/cli/pkg/types" bundleutils "github.com/aws/eks-anywhere/release/cli/pkg/util/bundles" "github.com/aws/eks-anywhere/release/cli/pkg/version" ) func GetPackagesBundle(r *releasetypes.ReleaseConfig, imageDigests releasetypes.ImageDigestsTable) (anywherev1alpha1.PackageBundle, error) { projectsInBundle := []string{"eks-anywhere-packages"} packagesArtifacts := map[string][]releasetypes.Artifact{} for _, project := range projectsInBundle { projectArtifacts, err := r.BundleArtifactsTable.Load(project) if err != nil { return anywherev1alpha1.PackageBundle{}, fmt.Errorf("artifacts for project %s not found in bundle artifacts table", project) } packagesArtifacts[project] = projectArtifacts } sortedComponentNames := bundleutils.SortArtifactsMap(packagesArtifacts) var sourceBranch string var componentChecksum string var Helmtag, Imagetag, Tokentag, Credentialtag string var Helmsha, Imagesha, Tokensha, Credentialsha string var err error bundleImageArtifacts := map[string]anywherev1alpha1.Image{} artifactHashes := []string{} // Find latest Packages dev build for the Helm chart and Image which will always start with `0.0.0` for helm chart and `v0.0.0` for images respectively. // If we can't find the build starting with our substring, we default to the original dev tag. // If we do find the Tag in Private ECR, but it doesn't exist in Public ECR Copy the image over so the helm chart will work correctly. if r.DevRelease && !r.DryRun { Helmtag, Helmsha, err = ecr.FilterECRRepoByTagPrefix(r.SourceClients.Packages.EcrClient, "eks-anywhere-packages", "0.0.0", r.BuildRepoBranchName, true) if err != nil { fmt.Printf("Error getting dev version helm tag EKS Anywhere package controller, using latest version %v", err) } Imagetag, Imagesha, err = ecr.FilterECRRepoByTagPrefix(r.SourceClients.Packages.EcrClient, "eks-anywhere-packages", "v0.0.0", r.BuildRepoBranchName, false) if err != nil { fmt.Printf("Error getting dev version Image tag EKS Anywhere package controller, using latest version %v", err) } PackageImage, err := ecrpublic.CheckImageExistence(fmt.Sprintf("%s/%s:%s", r.PackagesReleaseContainerRegistry, "eks-anywhere-packages", Imagetag), r.PackagesReleaseContainerRegistry, r.ReleaseClients.Packages.Client) if err != nil { fmt.Printf("Error checking image version existence for EKS Anywhere package controller, using latest version: %v", err) } if !PackageImage { fmt.Printf("Did not find the required helm image in Public ECR... copying image: %v\n", fmt.Sprintf("%s/%s:%s", r.PackagesReleaseContainerRegistry, "eks-anywhere-packages", Imagetag)) err := images.CopyToDestination(r.SourceClients.Packages.AuthConfig, r.ReleaseClients.Packages.AuthConfig, fmt.Sprintf("%s/%s:%s", r.PackagesSourceContainerRegistry, "eks-anywhere-packages", Imagetag), fmt.Sprintf("%s/%s:%s", r.PackagesReleaseContainerRegistry, "eks-anywhere-packages", Imagetag)) if err != nil { fmt.Printf("Error copying dev EKS Anywhere package controller image, to ECR Public: %v", err) } } Tokentag, Tokensha, err = ecr.FilterECRRepoByTagPrefix(r.SourceClients.Packages.EcrClient, "ecr-token-refresher", "v0.0.0", r.BuildRepoBranchName, false) if err != nil { fmt.Printf("Error getting dev version Image tag EKS Anywhere package token refresher, using latest version %v", err) } TokenImage, err := ecrpublic.CheckImageExistence(fmt.Sprintf("%s/%s:%s", r.PackagesReleaseContainerRegistry, "ecr-token-refresher", Tokentag), r.PackagesReleaseContainerRegistry, r.ReleaseClients.Packages.Client) if err != nil { fmt.Printf("Error checking image version existence for EKS Anywhere package token refresher, using latest version: %v", err) } if !TokenImage { fmt.Printf("Did not find the required helm image in Public ECR... copying image: %v\n", fmt.Sprintf("%s/%s:%s", r.PackagesReleaseContainerRegistry, "ecr-token-refresher", Tokentag)) err := images.CopyToDestination(r.SourceClients.Packages.AuthConfig, r.ReleaseClients.Packages.AuthConfig, fmt.Sprintf("%s/%s:%s", r.PackagesSourceContainerRegistry, "ecr-token-refresher", Tokentag), fmt.Sprintf("%s/%s:%s", r.PackagesReleaseContainerRegistry, "ecr-token-refresher", Tokentag)) if err != nil { fmt.Printf("Error copying dev EKS Anywhere package token refresher image, to ECR Public: %v", err) } } Credentialtag, Credentialsha, err = ecr.FilterECRRepoByTagPrefix(r.SourceClients.Packages.EcrClient, "credential-provider-package", "v0.0.0", r.BuildRepoBranchName, false) if err != nil { fmt.Printf("Error getting dev version Image tag EKS Anywhere package credential provider, using latest version %v", err) } CredentialImage, err := ecrpublic.CheckImageExistence(fmt.Sprintf("%s/%s:%s", r.PackagesReleaseContainerRegistry, "credential-provider-package", Credentialtag), r.PackagesReleaseContainerRegistry, r.ReleaseClients.Packages.Client) if err != nil { fmt.Printf("Error checking image version existence for EKS Anywhere package credential provider, using latest version: %v", err) } if !CredentialImage { fmt.Printf("Did not find the required helm image in Public ECR... copying image: %v\n", fmt.Sprintf("%s/%s:%s", r.PackagesReleaseContainerRegistry, "credential-provider-package", Credentialtag)) err := images.CopyToDestination(r.SourceClients.Packages.AuthConfig, r.ReleaseClients.Packages.AuthConfig, fmt.Sprintf("%s/%s:%s", r.PackagesSourceContainerRegistry, "credential-provider-package", Credentialtag), fmt.Sprintf("%s/%s:%s", r.PackagesReleaseContainerRegistry, "credential-provider-package", Credentialtag)) if err != nil { fmt.Printf("Error copying dev EKS Anywhere package credential provider image, to ECR Public: %v", err) } } } for _, componentName := range sortedComponentNames { for _, artifact := range packagesArtifacts[componentName] { if artifact.Image != nil { imageArtifact := artifact.Image sourceBranch = imageArtifact.SourcedFromBranch bundleImageArtifact := anywherev1alpha1.Image{} if strings.HasSuffix(imageArtifact.AssetName, "helm") { imageDigest, err := imageDigests.Load(imageArtifact.ReleaseImageURI) if err != nil { return anywherev1alpha1.PackageBundle{}, fmt.Errorf("loading digest from image digests table: %v", err) } if r.DevRelease && Helmsha != "" && Helmtag != "" { imageDigest = Helmsha imageArtifact.ReleaseImageURI = replaceTag(imageArtifact.ReleaseImageURI, Helmtag) } assetName := strings.TrimSuffix(imageArtifact.AssetName, "-helm") bundleImageArtifact = anywherev1alpha1.Image{ Name: assetName, Description: fmt.Sprintf("Helm chart for %s", assetName), URI: imageArtifact.ReleaseImageURI, ImageDigest: imageDigest, } } else { imageDigest, err := imageDigests.Load(imageArtifact.ReleaseImageURI) if err != nil { return anywherev1alpha1.PackageBundle{}, fmt.Errorf("loading digest from image digests table: %v", err) } if strings.HasSuffix(imageArtifact.AssetName, "eks-anywhere-packages") && r.DevRelease && Imagesha != "" && Imagetag != "" { imageDigest = Imagesha imageArtifact.ReleaseImageURI = replaceTag(imageArtifact.ReleaseImageURI, Imagetag) } else if strings.HasSuffix(imageArtifact.AssetName, "ecr-token-refresher") && r.DevRelease && Tokensha != "" && Tokentag != "" { imageDigest = Tokensha imageArtifact.ReleaseImageURI = replaceTag(imageArtifact.ReleaseImageURI, Tokentag) } else if strings.HasSuffix(imageArtifact.AssetName, "credential-provider-package") && r.DevRelease && Credentialsha != "" && Credentialtag != "" { imageDigest = Credentialsha imageArtifact.ReleaseImageURI = replaceTag(imageArtifact.ReleaseImageURI, Credentialtag) } bundleImageArtifact = anywherev1alpha1.Image{ Name: imageArtifact.AssetName, Description: fmt.Sprintf("Container image for %s image", imageArtifact.AssetName), OS: imageArtifact.OS, Arch: imageArtifact.Arch, URI: imageArtifact.ReleaseImageURI, ImageDigest: imageDigest, } } bundleImageArtifacts[imageArtifact.AssetName] = bundleImageArtifact artifactHashes = append(artifactHashes, bundleImageArtifact.ImageDigest) } } } if !r.DryRun && r.DevRelease { for _, componentName := range sortedComponentNames { for _, artifact := range packagesArtifacts[componentName] { if artifact.Image != nil { imageArtifact := artifact.Image sourceBranch = imageArtifact.SourcedFromBranch if strings.HasSuffix(imageArtifact.AssetName, "helm") { trimmedAsset := strings.TrimSuffix(artifact.Image.AssetName, "-helm") fmt.Printf("trimmedAsset=%v\n\n", trimmedAsset) helmDriver, err := helm.NewHelm() if err != nil { return anywherev1alpha1.PackageBundle{}, errors.Wrap(err, "creating helm client") } fmt.Printf("Modifying helm chart for %s\n", trimmedAsset) helmDest, err := helm.GetHelmDest(helmDriver, r, imageArtifact.SourceImageURI, trimmedAsset) if err != nil { return anywherev1alpha1.PackageBundle{}, errors.Wrap(err, "getting Helm destination:") } fmt.Printf("helmDest=%v\n", helmDest) fmt.Printf("Pulled helm chart locally to %s\n", helmDest) err = helm.ModifyAndPushChartYaml(*imageArtifact, r, helmDriver, helmDest, packagesArtifacts, bundleImageArtifacts) if err != nil { return anywherev1alpha1.PackageBundle{}, errors.Wrap(err, "modifying Chart.yaml and pushing Helm chart to destination:") } } } } } } if r.DryRun { componentChecksum = version.FakeComponentChecksum } else { componentChecksum = version.GenerateComponentHash(artifactHashes, r.DryRun) } version, err := version.BuildComponentVersion( version.NewVersionerWithGITTAG(r.BuildRepoSource, constants.PackagesProjectPath, sourceBranch, r), componentChecksum, ) if err != nil { return anywherev1alpha1.PackageBundle{}, errors.Wrap(err, "Error getting version for EKS Anywhere package controller") } bundle := anywherev1alpha1.PackageBundle{ Version: version, Controller: bundleImageArtifacts["eks-anywhere-packages"], TokenRefresher: bundleImageArtifacts["ecr-token-refresher"], CredentialProviderPackage: bundleImageArtifacts["credential-provider-package"], HelmChart: bundleImageArtifacts["eks-anywhere-packages-helm"], } return bundle, nil } // replaceTag is used to replace the tag of an Image URI with a string. func replaceTag(uri, tag string) string { NewURIList := strings.Split(uri, ":") if len(NewURIList) < 2 { return uri } NewURIList[len(NewURIList)-1] = tag uri = strings.Join(NewURIList[:], ":") return uri }