diff --git a/cmd/util/doc-gen/generators/traitmetadatagen.go b/cmd/util/doc-gen/generators/traitmetadatagen.go index 40bae9c6cc..07180636f4 100644 --- a/cmd/util/doc-gen/generators/traitmetadatagen.go +++ b/cmd/util/doc-gen/generators/traitmetadatagen.go @@ -70,12 +70,16 @@ func (g *traitMetaDataGen) Filename() string { } func (g *traitMetaDataGen) Filter(context *generator.Context, t *types.Type) bool { + filter := false for _, c := range t.CommentLines { if strings.Contains(c, tagTrait) { - return true + filter = true + } + if strings.Contains(c, tagInternal) { + filter = false } } - return false + return filter } func (g *traitMetaDataGen) GenerateType(context *generator.Context, t *types.Type, out io.Writer) error { diff --git a/docs/modules/ROOT/nav.adoc b/docs/modules/ROOT/nav.adoc index a70b946eb0..9f5c42ec3a 100644 --- a/docs/modules/ROOT/nav.adoc +++ b/docs/modules/ROOT/nav.adoc @@ -83,7 +83,6 @@ ** xref:traits:prometheus.adoc[Prometheus] ** xref:traits:pull-secret.adoc[Pull Secret] ** xref:traits:quarkus.adoc[Quarkus] -** xref:traits:registry.adoc[Registry] ** xref:traits:resume.adoc[Resume] ** xref:traits:route.adoc[Route] ** xref:traits:security-context.adoc[Security Context] diff --git a/docs/modules/ROOT/partials/apis/camel-k-crds.adoc b/docs/modules/ROOT/partials/apis/camel-k-crds.adoc index 574a2be220..fd9da8052c 100644 --- a/docs/modules/ROOT/partials/apis/camel-k-crds.adoc +++ b/docs/modules/ROOT/partials/apis/camel-k-crds.adoc @@ -2714,7 +2714,7 @@ NOTE: Compiling to a native executable, requires at least 4GiB of memory, so the | -The Registry trait sets up Maven to use the Image registry as a Maven repository. +The Registry trait sets up Maven to use the Image registry as a Maven repository (support removed since version 2.5.0). Deprecated: use jvm trait or read documentation. |`addons` + @@ -5946,7 +5946,7 @@ The configuration of Quarkus trait | -The configuration of Registry trait +The configuration of Registry trait (support removed since version 2.5.0). Deprecated: use jvm trait or read documentation. |`route` + @@ -8383,7 +8383,7 @@ Deprecated: for backward compatibility. * <<#_camel_apache_org_v1_IntegrationKitTraits, IntegrationKitTraits>> * <<#_camel_apache_org_v1_Traits, Traits>> -WARNING: The Registry trait is **deprecated** and will removed in future release versions. +WARNING: The Registry trait was deprecated in version 2.2.0 and is no longer active since version 2.5.0. The Registry trait sets up Maven to use the Image registry as a Maven repository. diff --git a/docs/modules/traits/pages/registry.adoc b/docs/modules/traits/pages/registry.adoc deleted file mode 100644 index 3043f2d211..0000000000 --- a/docs/modules/traits/pages/registry.adoc +++ /dev/null @@ -1,36 +0,0 @@ -= Registry Trait - -// Start of autogenerated code - DO NOT EDIT! (badges) -image:https://img.shields.io/badge/2.2.0-white?label=Deprecated&labelColor=C40C0C&color=gray[Deprecated Badge] -// End of autogenerated code - DO NOT EDIT! (badges) -// Start of autogenerated code - DO NOT EDIT! (description) -WARNING: The Registry trait is **deprecated** and will removed in future release versions. - -The Registry trait sets up Maven to use the Image registry -as a Maven repository. - - -This trait is available in the following profiles: **Kubernetes, Knative, OpenShift**. - -// End of autogenerated code - DO NOT EDIT! (description) -// Start of autogenerated code - DO NOT EDIT! (configuration) -== Configuration - -Trait properties can be specified when running any integration with the CLI: -[source,console] ----- -$ kamel run --trait registry.[key]=[value] integration.yaml ----- -The following configuration options are available: - -[cols="2m,1m,5a"] -|=== -|Property | Type | Description - -| registry.enabled -| bool -| Can be used to enable or disable a trait. All traits share this common property. - -|=== - -// End of autogenerated code - DO NOT EDIT! (configuration) diff --git a/helm/camel-k/crds/crd-integration-kit.yaml b/helm/camel-k/crds/crd-integration-kit.yaml index 36e766edc1..0c9c03bec8 100644 --- a/helm/camel-k/crds/crd-integration-kit.yaml +++ b/helm/camel-k/crds/crd-integration-kit.yaml @@ -423,7 +423,7 @@ spec: type: object registry: description: |- - The Registry trait sets up Maven to use the Image registry as a Maven repository. + The Registry trait sets up Maven to use the Image registry as a Maven repository (support removed since version 2.5.0). Deprecated: use jvm trait or read documentation. properties: configuration: diff --git a/helm/camel-k/crds/crd-integration-platform.yaml b/helm/camel-k/crds/crd-integration-platform.yaml index 793693bd3e..c21fdca750 100644 --- a/helm/camel-k/crds/crd-integration-platform.yaml +++ b/helm/camel-k/crds/crd-integration-platform.yaml @@ -1890,7 +1890,7 @@ spec: type: object registry: description: |- - The configuration of Registry trait + The configuration of Registry trait (support removed since version 2.5.0). Deprecated: use jvm trait or read documentation. properties: configuration: @@ -3988,7 +3988,7 @@ spec: type: object registry: description: |- - The configuration of Registry trait + The configuration of Registry trait (support removed since version 2.5.0). Deprecated: use jvm trait or read documentation. properties: configuration: diff --git a/helm/camel-k/crds/crd-integration-profile.yaml b/helm/camel-k/crds/crd-integration-profile.yaml index ba42359f8b..d96df69f0e 100644 --- a/helm/camel-k/crds/crd-integration-profile.yaml +++ b/helm/camel-k/crds/crd-integration-profile.yaml @@ -1765,7 +1765,7 @@ spec: type: object registry: description: |- - The configuration of Registry trait + The configuration of Registry trait (support removed since version 2.5.0). Deprecated: use jvm trait or read documentation. properties: configuration: @@ -3745,7 +3745,7 @@ spec: type: object registry: description: |- - The configuration of Registry trait + The configuration of Registry trait (support removed since version 2.5.0). Deprecated: use jvm trait or read documentation. properties: configuration: diff --git a/helm/camel-k/crds/crd-integration.yaml b/helm/camel-k/crds/crd-integration.yaml index 8795ced1d5..7f99d90d69 100644 --- a/helm/camel-k/crds/crd-integration.yaml +++ b/helm/camel-k/crds/crd-integration.yaml @@ -7781,7 +7781,7 @@ spec: type: object registry: description: |- - The configuration of Registry trait + The configuration of Registry trait (support removed since version 2.5.0). Deprecated: use jvm trait or read documentation. properties: configuration: diff --git a/helm/camel-k/crds/crd-kamelet-binding.yaml b/helm/camel-k/crds/crd-kamelet-binding.yaml index 1de31c92ee..2805a4bc92 100644 --- a/helm/camel-k/crds/crd-kamelet-binding.yaml +++ b/helm/camel-k/crds/crd-kamelet-binding.yaml @@ -7854,7 +7854,7 @@ spec: type: object registry: description: |- - The configuration of Registry trait + The configuration of Registry trait (support removed since version 2.5.0). Deprecated: use jvm trait or read documentation. properties: configuration: diff --git a/helm/camel-k/crds/crd-pipe.yaml b/helm/camel-k/crds/crd-pipe.yaml index a3ae76d7c6..77aa04e8e5 100644 --- a/helm/camel-k/crds/crd-pipe.yaml +++ b/helm/camel-k/crds/crd-pipe.yaml @@ -7852,7 +7852,7 @@ spec: type: object registry: description: |- - The configuration of Registry trait + The configuration of Registry trait (support removed since version 2.5.0). Deprecated: use jvm trait or read documentation. properties: configuration: diff --git a/pkg/apis/camel/v1/common_types.go b/pkg/apis/camel/v1/common_types.go index 983b565603..ed4bb2af05 100644 --- a/pkg/apis/camel/v1/common_types.go +++ b/pkg/apis/camel/v1/common_types.go @@ -233,7 +233,7 @@ type Traits struct { PullSecret *trait.PullSecretTrait `property:"pull-secret" json:"pull-secret,omitempty"` // The configuration of Quarkus trait Quarkus *trait.QuarkusTrait `property:"quarkus" json:"quarkus,omitempty"` - // The configuration of Registry trait + // The configuration of Registry trait (support removed since version 2.5.0). // Deprecated: use jvm trait or read documentation. Registry *trait.RegistryTrait `property:"registry" json:"registry,omitempty"` // The configuration of Route trait diff --git a/pkg/apis/camel/v1/integrationkit_types.go b/pkg/apis/camel/v1/integrationkit_types.go index b87eda9b47..d6b6957934 100644 --- a/pkg/apis/camel/v1/integrationkit_types.go +++ b/pkg/apis/camel/v1/integrationkit_types.go @@ -88,7 +88,7 @@ type IntegrationKitTraits struct { // It's enabled by default. // NOTE: Compiling to a native executable, requires at least 4GiB of memory, so the Pod running the native build must have enough memory available. Quarkus *trait.QuarkusTrait `property:"quarkus" json:"quarkus,omitempty"` - // The Registry trait sets up Maven to use the Image registry as a Maven repository. + // The Registry trait sets up Maven to use the Image registry as a Maven repository (support removed since version 2.5.0). // Deprecated: use jvm trait or read documentation. Registry *trait.RegistryTrait `property:"registry" json:"registry,omitempty"` // The collection of addon trait configurations diff --git a/pkg/apis/camel/v1/trait/registry.go b/pkg/apis/camel/v1/trait/registry.go index b35d74beb2..2572165832 100644 --- a/pkg/apis/camel/v1/trait/registry.go +++ b/pkg/apis/camel/v1/trait/registry.go @@ -17,13 +17,13 @@ limitations under the License. package trait -// WARNING: The Registry trait is **deprecated** and will removed in future release versions. +// WARNING: The Registry trait was deprecated in version 2.2.0 and is no longer active since version 2.5.0. // // The Registry trait sets up Maven to use the Image registry // as a Maven repository. // // +camel-k:trait=registry. -// +camel-k:deprecated=2.2.0. +// +camel-k:internal. type RegistryTrait struct { Trait `property:",squash" json:",inline"` } diff --git a/pkg/cmd/run.go b/pkg/cmd/run.go index b9434a4613..52419bdfdd 100644 --- a/pkg/cmd/run.go +++ b/pkg/cmd/run.go @@ -18,32 +18,23 @@ limitations under the License. package cmd import ( - "archive/zip" "context" "errors" // this is needed to generate an SHA1 sum for Jars // #nosec G501 - "crypto/md5" + // #nosec G505 - "crypto/sha1" - "encoding/hex" + "encoding/json" - "encoding/xml" "fmt" - "hash" - "io" - "io/fs" "net/url" "os" "os/signal" - "path/filepath" "reflect" - "regexp" "strings" "syscall" - spectrum "github.com/container-tools/spectrum/pkg/builder" "github.com/magiconair/properties" "github.com/spf13/cobra" @@ -61,15 +52,12 @@ import ( v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" "github.com/apache/camel-k/v2/pkg/client" "github.com/apache/camel-k/v2/pkg/cmd/source" - "github.com/apache/camel-k/v2/pkg/platform" "github.com/apache/camel-k/v2/pkg/trait" "github.com/apache/camel-k/v2/pkg/util" "github.com/apache/camel-k/v2/pkg/util/camel" - "github.com/apache/camel-k/v2/pkg/util/defaults" "github.com/apache/camel-k/v2/pkg/util/dsl" "github.com/apache/camel-k/v2/pkg/util/kubernetes" k8slog "github.com/apache/camel-k/v2/pkg/util/kubernetes/log" - "github.com/apache/camel-k/v2/pkg/util/maven" "github.com/apache/camel-k/v2/pkg/util/property" "github.com/apache/camel-k/v2/pkg/util/resource" "github.com/apache/camel-k/v2/pkg/util/sync" @@ -552,7 +540,7 @@ func (o *runCmdOptions) createOrUpdateIntegration(cmd *cobra.Command, c client.C return nil, err } - if err := o.applyDependencies(cmd, c, integration, name); err != nil { + if err := o.applyDependencies(cmd, integration); err != nil { return nil, err } @@ -819,67 +807,29 @@ func (o *runCmdOptions) convertToTraitParameter(c client.Client, value, traitPar return traits, nil } -func (o *runCmdOptions) applyDependencies(cmd *cobra.Command, c client.Client, it *v1.Integration, name string) error { - var platform *v1.IntegrationPlatform +func (o *runCmdOptions) applyDependencies(cmd *cobra.Command, it *v1.Integration) error { var catalog *camel.RuntimeCatalog for _, item := range o.Dependencies { - // Deprecated: won't be supported in future releases - if strings.HasPrefix(item, "file://") || strings.HasPrefix(item, "http://") || strings.HasPrefix(item, "https://") { - if platform == nil { - var err error - platform, err = o.getPlatform(cmd, c, it) - if err != nil { - return err - } - } - fmt.Fprintf(cmd.ErrOrStderr(), "Warning: this feature is deprecated and may disappear in future release. Use jvm trait instead.\n") - if err := o.uploadDependency(platform, item, name, cmd, it); err != nil { - return fmt.Errorf("error trying to upload %s to the Image Registry.: %w", item, err) + if catalog == nil { + // The catalog used for lightweight validation of Camel components. + // The exact runtime version is not used here since resolving the runtime version may be + // a costly operation and most of the use cases should be covered by the default catalog. + // And the validation only warns potential misusage of Camel components at the CLI level, + // so strictness of catalog version is not necessary here. + var err error + catalog, err = createCamelCatalog() + if err != nil { + return err } - } else { if catalog == nil { - // The catalog used for lightweight validation of Camel components. - // The exact runtime version is not used here since resolving the runtime version may be - // a costly operation and most of the use cases should be covered by the default catalog. - // And the validation only warns potential misusage of Camel components at the CLI level, - // so strictness of catalog version is not necessary here. - var err error - catalog, err = createCamelCatalog() - if err != nil { - return err - } - if catalog == nil { - return fmt.Errorf("error trying to load the default Camel catalog") - } + return fmt.Errorf("error trying to load the default Camel catalog") } - addDependency(cmd, it, item, catalog) } - } + addDependency(cmd, it, item, catalog) - return nil -} - -func (o *runCmdOptions) getPlatform(cmd *cobra.Command, c client.Client, it *v1.Integration) (*v1.IntegrationPlatform, error) { - // let's also enable the registry trait if not explicitly disabled - if !util.StringSliceContainsAnyOf(o.Traits, "registry.enabled=false") { - o.Traits = append(o.Traits, "registry.enabled=true") - } - pl, err := platform.GetForResource(o.Context, c, it) - if err != nil { - return nil, err - } - if ca := pl.Status.Build.Registry.CA; ca != "" { - o.PrintfVerboseOutf(cmd, "We've noticed the image registry is configured with a custom certificate [%s] \n", ca) - o.PrintVerboseOut(cmd, "Please make sure Kamel CLI is configured to use it or the operation will fail.") - o.PrintVerboseOut(cmd, "More information can be found here https://nodejs.org/api/cli.html#cli_node_extra_ca_certs_file") - } - if secret := pl.Status.Build.Registry.Secret; secret != "" { - o.PrintfVerboseOutf(cmd, "We've noticed the image registry is configured with a Secret [%s] \n", secret) - o.PrintVerboseOut(cmd, "Please configure Docker authentication correctly or the operation will fail (by default it's $HOME/.docker/config.json).") - o.PrintVerboseOut(cmd, "More information can be found here https://docs.docker.com/engine/reference/commandline/login/") } - return pl, nil + return nil } func (o *runCmdOptions) GetIntegrationName(sources []string) string { @@ -979,405 +929,3 @@ func resolvePodTemplate(ctx context.Context, cmd *cobra.Command, templateSrc str } return err } - -func parseFileURI(uri string) *url.URL { - file := new(url.URL) - file.Scheme = "file" - path := strings.TrimPrefix(uri, "file://") - i := strings.IndexByte(path, '?') - if i > 0 { - file.Path = path[:i] - file.RawQuery = path[i+1:] - } else { - file.Path = path - } - return file -} - -func (o *runCmdOptions) getRegistry(platform *v1.IntegrationPlatform) string { - registry := o.RegistryOptions.Get("registry") - if registry != "" { - return registry - } - return platform.Status.Build.Registry.Address -} - -func (o *runCmdOptions) skipChecksums() bool { - return o.RegistryOptions.Get("skipChecksums") == "true" -} - -func (o *runCmdOptions) skipPom() bool { - return o.RegistryOptions.Get("skipPOM") == "true" -} - -func (o *runCmdOptions) classpath() bool { - return o.RegistryOptions.Get("classpath") == "true" -} - -func (o *runCmdOptions) getTargetPath() string { - return o.RegistryOptions.Get("targetPath") -} - -// Deprecated: won't be supported in future releases. -func (o *runCmdOptions) uploadDependency(platform *v1.IntegrationPlatform, item string, integrationName string, cmd *cobra.Command, integration *v1.Integration) error { - var localPath string - if strings.HasPrefix(item, "http://") || strings.HasPrefix(item, "https://") { - idx := strings.LastIndex(item, "|") - var depURL string - if idx == -1 { - depURL = item - o.RegistryOptions = make(url.Values) - } else { - query := item[idx+1:] - options, err := url.ParseQuery(query) - if err != nil { - return fmt.Errorf("invalid http dependency options %s: %w", query, err) - } - o.RegistryOptions = options - depURL = item[:idx] - } - - uri, err := url.Parse(depURL) - if err != nil { - return fmt.Errorf("invalid http dependency url %s: %w", depURL, err) - } else if localPath, err = downloadDependency(o.Context, *uri); err != nil { - return fmt.Errorf("could not download http dependency %s: %w", depURL, err) - } - // Remove the temporary file - defer os.Remove(localPath) - } else { - uri := parseFileURI(item) - o.RegistryOptions = uri.Query() - localPath = uri.Path - } - targetPath := o.getTargetPath() - options := o.getSpectrumOptions(platform, cmd) - dirName, err := getDirName(localPath) - if err != nil { - return err - } - - return filepath.WalkDir(localPath, func(path string, d fs.DirEntry, err error) error { - if err != nil { - return err - } - if d.IsDir() { - return nil - } - // Let's try to build a default Maven GAV from the path - gav, err := createDefaultGav(path, dirName, integrationName) - if err != nil { - return err - } - // When uploading, there are three cases: POM files, JAR files and the rest which will be mounted on the filesystem - switch { - case isPom(path): - gav := extractGavFromPom(path, gav) - return o.uploadAsMavenArtifact(gav, path, platform, integration.Namespace, options, cmd) - case isJar(path): - // Try to upload pom in JAR and extract it's GAV - gav = o.uploadPomFromJar(gav, path, platform, integration.Namespace, options, cmd) - // add JAR to dependency list - dependency := fmt.Sprintf("mvn:%s:%s:%s:%s", gav.GroupID, gav.ArtifactID, gav.Type, gav.Version) - o.PrintfVerboseOutf(cmd, "Added %s to the Integration's dependency list \n", dependency) - integration.Spec.AddDependency(dependency) - // Upload JAR - return o.uploadAsMavenArtifact(gav, path, platform, integration.Namespace, options, cmd) - default: - mountPath, err := getMountPath(targetPath, dirName, path) - if err != nil { - return err - } - dependency := fmt.Sprintf("registry-mvn:%s:%s:%s:%s@%s", gav.GroupID, gav.ArtifactID, gav.Type, gav.Version, mountPath) - if o.classpath() { - dependency = fmt.Sprintf("%s@%s", dependency, "classpath") - } - o.PrintfVerboseOutf(cmd, "Added %s to the Integration's dependency list \n", dependency) - integration.Spec.AddDependency(dependency) - return o.uploadAsMavenArtifact(gav, path, platform, integration.Namespace, options, cmd) - } - }) -} - -func getMountPath(targetPath string, dirName string, path string) (string, error) { - // if the target path is a file then use that as the exact mount path - if filepath.Ext(targetPath) != "" { - return targetPath, nil - } - // else build a mount path based on the filename relative to the base directory - // (in case we are uploading multiple files with the same name) - localRelativePath, err := filepath.Rel(dirName, path) - if err != nil { - return "", err - } - return filepath.Join(targetPath, localRelativePath), nil -} - -func (o *runCmdOptions) uploadPomFromJar(gav maven.Dependency, path string, platform *v1.IntegrationPlatform, ns string, options spectrum.Options, cmd *cobra.Command) maven.Dependency { - _ = util.WithTempDir("camel-k", func(tmpDir string) error { - pomPath := filepath.Join(tmpDir, "pom.xml") - jar, err := zip.OpenReader(path) - if err != nil { - return err - } - defer jar.Close() - regPom := regexp.MustCompile(`META-INF/maven/.*/.*/pom\.xml`) - regPomProperties := regexp.MustCompile(`META-INF/maven/.*/.*/pom\.properties`) - foundPom := false - foundProperties := false - pomExtracted := false - for _, f := range jar.File { - if regPom.MatchString(f.Name) { - foundPom = true - pomExtracted = extractFromZip(pomPath, f) - } else if regPomProperties.MatchString(f.Name) { - foundProperties = true - if dep, ok := o.extractGav(f, path, cmd); ok { - gav = dep - } - } - if foundPom && foundProperties { - break - } - } - if pomExtracted { - if o.skipPom() { - o.PrintfVerboseOutf(cmd, "Skipping uploading extracted POM from %s \n", path) - } else { - gav.Type = "pom" - // Swallow error as this is not a mandatory step - _ = o.uploadAsMavenArtifact(gav, pomPath, platform, ns, options, cmd) - } - } - return nil - }) - gav.Type = "jar" - return gav -} - -func extractFromZip(dst string, src *zip.File) bool { - file, err := os.Create(dst) - if err != nil { - return false - } - defer file.Close() - rc, err := src.Open() - if err != nil { - return false - } - defer rc.Close() - // no DoS on client side - // #nosec G110 - _, err = io.Copy(file, rc) - return err == nil -} - -func (o *runCmdOptions) extractGav(src *zip.File, localPath string, cmd *cobra.Command) (maven.Dependency, bool) { - rc, err := src.Open() - if err != nil { - return maven.Dependency{}, false - } - defer rc.Close() - data, err := io.ReadAll(rc) - if err != nil { - o.PrintfVerboseErrf(cmd, "Error while reading pom.properties from [%s], switching to default: \n %s err \n", localPath, err) - return maven.Dependency{}, false - } - prop, err := properties.Load(data, properties.UTF8) - if err != nil { - o.PrintfVerboseErrf(cmd, "Error while reading pom.properties from [%s], switching to default: \n %s err \n", localPath, err) - return maven.Dependency{}, false - } - - groupID, ok := prop.Get("groupId") - if !ok { - o.PrintfVerboseErrf(cmd, "Couldn't find groupId property while reading pom.properties from [%s], switching to default \n", localPath) - return maven.Dependency{}, false - } - artifactID, ok := prop.Get("artifactId") - if !ok { - o.PrintfVerboseErrf(cmd, "Couldn't find artifactId property while reading pom.properties from [%s], switching to default \n", localPath) - return maven.Dependency{}, false - } - version, ok := prop.Get("version") - if !ok { - o.PrintfVerboseErrf(cmd, "Couldn't find version property while reading pom.properties from [%s], switching to default \n", localPath) - return maven.Dependency{}, false - } - return maven.Dependency{ - GroupID: groupID, - ArtifactID: artifactID, - Type: "jar", - Version: version, - }, true -} - -func (o *runCmdOptions) uploadAsMavenArtifact(dependency maven.Dependency, path string, platform *v1.IntegrationPlatform, ns string, options spectrum.Options, cmd *cobra.Command) error { - artifactHTTPPath := getArtifactHTTPPath(dependency, platform, ns) - options.Target = fmt.Sprintf("%s/%s:%s", o.getRegistry(platform), artifactHTTPPath, dependency.Version) - _, err := spectrum.Build(options, fmt.Sprintf("%s:.", path)) - if err != nil { - return err - } - o.PrintfVerboseOutf(cmd, "Uploaded: %s to %s \n", path, options.Target) - if o.skipChecksums() { - o.PrintfVerboseOutf(cmd, "Skipping generating and uploading checksum files for %s \n", path) - return nil - } - return o.uploadChecksumFiles(path, options, platform, artifactHTTPPath, dependency) -} - -// Currently swallows errors because our Project model is incomplete. -// Most of the time it is irrelevant for our use case (GAV). -// -//nolint:errcheck -func extractGavFromPom(path string, gav maven.Dependency) maven.Dependency { - var project maven.Project - file, err := os.Open(path) - if err != nil { - return gav - } - defer file.Close() - content, err := io.ReadAll(file) - if err != nil { - return gav - } - xml.Unmarshal(content, &project) - if project.GroupID != "" { - gav.GroupID = project.GroupID - } - if project.ArtifactID != "" { - gav.ArtifactID = project.ArtifactID - } - if project.Version != "" { - gav.Version = project.Version - } - gav.Type = "pom" - return gav -} - -//nolint:gosec -func (o *runCmdOptions) uploadChecksumFiles(path string, options spectrum.Options, platform *v1.IntegrationPlatform, artifactHTTPPath string, dependency maven.Dependency) error { - return util.WithTempDir("camel-k", func(tmpDir string) error { - if err := o.uploadChecksumFile(md5.New(), tmpDir, "_md5", path, options, platform, artifactHTTPPath, dependency); err != nil { - return err - } - return o.uploadChecksumFile(sha1.New(), tmpDir, "_sha1", path, options, platform, artifactHTTPPath, dependency) - }) -} - -func (o *runCmdOptions) uploadChecksumFile(hash hash.Hash, tmpDir string, ext string, path string, options spectrum.Options, platform *v1.IntegrationPlatform, artifactHTTPPath string, dependency maven.Dependency) error { - file, err := os.Open(path) - if err != nil { - return err - } - defer file.Close() - _, err = io.Copy(hash, file) - if err != nil { - return err - } - - filename := "maven_" + filepath.Base(path) + ext - filepath := filepath.Join(tmpDir, filename) - - if err = writeChecksumToFile(filepath, hash); err != nil { - return err - } - options.Target = fmt.Sprintf("%s/%s%s:%s", o.getRegistry(platform), artifactHTTPPath, ext, dependency.Version) - _, err = spectrum.Build(options, fmt.Sprintf("%s:.", filepath)) - return err -} - -func writeChecksumToFile(filepath string, hash hash.Hash) error { - file, err := os.Create(filepath) - if err != nil { - return err - } - defer file.Close() - - _, err = file.WriteString(hex.EncodeToString(hash.Sum(nil))) - return err -} - -func (o *runCmdOptions) getSpectrumOptions(platform *v1.IntegrationPlatform, cmd *cobra.Command) spectrum.Options { - insecure := platform.Status.Build.Registry.Insecure - var stdout io.Writer - if o.Verbose { - stdout = cmd.OutOrStdout() - } - options := spectrum.Options{ - PullInsecure: true, - PushInsecure: insecure, - PullConfigDir: "", - PushConfigDir: "", - Base: "", - Stdout: stdout, - Stderr: cmd.OutOrStderr(), - Recursive: false, - } - return options -} - -func getArtifactHTTPPath(dependency maven.Dependency, platform *v1.IntegrationPlatform, ns string) string { - artifactHTTPPath := fmt.Sprintf("maven_%s_%s_%s_%s-%s_%s", dependency.GroupID, dependency.ArtifactID, dependency.Version, dependency.ArtifactID, dependency.Version, dependency.Type) - // Image repository names must be lower cased - artifactHTTPPath = strings.ToLower(artifactHTTPPath) - // Some vendors don't allow '/' or '.' in repository name so let's replace them with '_' - artifactHTTPPath = strings.ReplaceAll(artifactHTTPPath, "/", "_") - artifactHTTPPath = strings.ReplaceAll(artifactHTTPPath, ".", "_") - organization := platform.Status.Build.Registry.Organization - if organization == "" { - organization = ns - } - return fmt.Sprintf("%s/%s", organization, artifactHTTPPath) -} - -func createDefaultGav(path string, dirName string, integrationName string) (maven.Dependency, error) { - // let's set the default ArtifactId using the integration name and the file's relative path - // we use the relative path in case of nested files that might have the same name - // we replace the file seperators with dots to comply with Maven GAV naming conventions. - fileRelPath, ext, err := getFileRelativePathAndExtension(path, dirName) - if err != nil { - return maven.Dependency{}, err - } - - defaultArtifactID := integrationName + "-" + strings.ReplaceAll(fileRelPath, string(os.PathSeparator), ".") - defaultGroupID := "org.apache.camel.k.external" - defaultVersion := defaults.Version - - return maven.Dependency{ - GroupID: defaultGroupID, - ArtifactID: defaultArtifactID, - Type: ext, - Version: defaultVersion, - }, nil -} - -func isPom(path string) bool { - return strings.HasSuffix(path, ".pom") || strings.HasSuffix(path, "pom.xml") -} - -func isJar(path string) bool { - return strings.HasSuffix(path, ".jar") -} - -func getFileRelativePathAndExtension(path string, dirName string) (string, string, error) { - extension := filepath.Ext(path) - name, err := filepath.Rel(dirName, path) - if err != nil { - return "", "", err - } - return name[0 : len(name)-len(extension)], extension[1:], nil -} - -func getDirName(path string) (string, error) { - parentDir := path - fileInfo, err := os.Stat(path) - if err != nil { - return "", err - } - if !fileInfo.IsDir() { - parentDir = filepath.Dir(parentDir) - } - return parentDir, nil -} diff --git a/pkg/cmd/run_support.go b/pkg/cmd/run_support.go index 882adb9793..af2d7a3fe8 100644 --- a/pkg/cmd/run_support.go +++ b/pkg/cmd/run_support.go @@ -20,14 +20,9 @@ package cmd import ( "context" "fmt" - "io" - "net/http" - "net/url" "os" - "path/filepath" "reflect" "strings" - "time" v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" "github.com/apache/camel-k/v2/pkg/client" @@ -123,39 +118,6 @@ func fromMapToProperties(data interface{}, toString func(reflect.Value) string, return result, nil } -// downloadDependency downloads the file located at the given URL into a temporary folder and returns the local path to the generated temporary file. -func downloadDependency(ctx context.Context, url url.URL) (string, error) { - tctx, cancel := context.WithTimeout(ctx, 3*time.Second) - defer cancel() - - req, err := http.NewRequestWithContext(tctx, http.MethodGet, url.String(), nil) - if err != nil { - return "", err - } - res, err := http.DefaultClient.Do(req) - if err != nil { - return "", err - } - defer res.Body.Close() - base := filepath.Base(url.Path) - if base == "." || base == "/" || filepath.Ext(base) == "" { - base = filepath.Base(url.String()) - if base == "." || base == "/" { - base = "tmp" - } - } - out, err := os.CreateTemp("", fmt.Sprintf("*.%s", base)) - if err != nil { - return "", err - } - defer out.Close() - _, err = io.Copy(out, res.Body) - if err != nil { - return "", err - } - return out.Name(), nil -} - func validatePropertyFiles(propertyFiles []string) error { for _, fileName := range propertyFiles { if err := validatePropertyFile(fileName); err != nil { diff --git a/pkg/cmd/run_support_test.go b/pkg/cmd/run_support_test.go index 5ef9830686..81d2088554 100644 --- a/pkg/cmd/run_support_test.go +++ b/pkg/cmd/run_support_test.go @@ -18,14 +18,9 @@ limitations under the License. package cmd import ( - "context" - "net/url" - "os" - "strings" "testing" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func TestFilterFileLocation(t *testing.T) { @@ -45,41 +40,6 @@ func TestFilterFileLocation(t *testing.T) { assert.Equal(t, "/validfile", filteredOptions[2]) } -func TestDownloadDependencyWithBadURL(t *testing.T) { - u, _ := url.Parse("http://foo") - _, err := downloadDependency(context.Background(), *u) - require.Error(t, err) -} - -func TestDownloadDependencyWithFileNameInURL(t *testing.T) { - u, _ := url.Parse("https://repo1.maven.org/maven2/org/apache/camel/camel-core/3.18.2/camel-core-3.18.2.jar") - path, err := downloadDependency(context.Background(), *u) - t.Cleanup(func() { os.Remove(path) }) - require.NoError(t, err) - assert.True(t, strings.HasSuffix(path, "camel-core-3.18.2.jar"), "The name of the jar file is expected") - _, err = os.Stat(path) - require.NoError(t, err) -} - -func TestDownloadDependencyWithFileNameInQuery(t *testing.T) { - u, _ := url.Parse("https://search.maven.org/remotecontent?filepath=org/apache/camel/quarkus/camel-quarkus-file/2.12.0/camel-quarkus-file-2.12.0.jar") - path, err := downloadDependency(context.Background(), *u) - t.Cleanup(func() { os.Remove(path) }) - require.NoError(t, err) - assert.True(t, strings.HasSuffix(path, "camel-quarkus-file-2.12.0.jar"), "The name of the jar file is expected") - _, err = os.Stat(path) - require.NoError(t, err) -} - -func TestDownloadDependencyWithoutFileName(t *testing.T) { - u, _ := url.Parse("https://search.maven.org") - path, err := downloadDependency(context.Background(), *u) - t.Cleanup(func() { os.Remove(path) }) - require.NoError(t, err) - _, err = os.Stat(path) - require.NoError(t, err) -} - func TestExtractTraitNames(t *testing.T) { traitProps := []string{"container.enabled=true", "no-trait.noval=1", "nothing"} tn := extractTraitNames(traitProps) diff --git a/pkg/resources/config/crd/bases/camel.apache.org_integrationkits.yaml b/pkg/resources/config/crd/bases/camel.apache.org_integrationkits.yaml index 36e766edc1..0c9c03bec8 100644 --- a/pkg/resources/config/crd/bases/camel.apache.org_integrationkits.yaml +++ b/pkg/resources/config/crd/bases/camel.apache.org_integrationkits.yaml @@ -423,7 +423,7 @@ spec: type: object registry: description: |- - The Registry trait sets up Maven to use the Image registry as a Maven repository. + The Registry trait sets up Maven to use the Image registry as a Maven repository (support removed since version 2.5.0). Deprecated: use jvm trait or read documentation. properties: configuration: diff --git a/pkg/resources/config/crd/bases/camel.apache.org_integrationplatforms.yaml b/pkg/resources/config/crd/bases/camel.apache.org_integrationplatforms.yaml index 793693bd3e..c21fdca750 100644 --- a/pkg/resources/config/crd/bases/camel.apache.org_integrationplatforms.yaml +++ b/pkg/resources/config/crd/bases/camel.apache.org_integrationplatforms.yaml @@ -1890,7 +1890,7 @@ spec: type: object registry: description: |- - The configuration of Registry trait + The configuration of Registry trait (support removed since version 2.5.0). Deprecated: use jvm trait or read documentation. properties: configuration: @@ -3988,7 +3988,7 @@ spec: type: object registry: description: |- - The configuration of Registry trait + The configuration of Registry trait (support removed since version 2.5.0). Deprecated: use jvm trait or read documentation. properties: configuration: diff --git a/pkg/resources/config/crd/bases/camel.apache.org_integrationprofiles.yaml b/pkg/resources/config/crd/bases/camel.apache.org_integrationprofiles.yaml index ba42359f8b..d96df69f0e 100644 --- a/pkg/resources/config/crd/bases/camel.apache.org_integrationprofiles.yaml +++ b/pkg/resources/config/crd/bases/camel.apache.org_integrationprofiles.yaml @@ -1765,7 +1765,7 @@ spec: type: object registry: description: |- - The configuration of Registry trait + The configuration of Registry trait (support removed since version 2.5.0). Deprecated: use jvm trait or read documentation. properties: configuration: @@ -3745,7 +3745,7 @@ spec: type: object registry: description: |- - The configuration of Registry trait + The configuration of Registry trait (support removed since version 2.5.0). Deprecated: use jvm trait or read documentation. properties: configuration: diff --git a/pkg/resources/config/crd/bases/camel.apache.org_integrations.yaml b/pkg/resources/config/crd/bases/camel.apache.org_integrations.yaml index 8795ced1d5..7f99d90d69 100644 --- a/pkg/resources/config/crd/bases/camel.apache.org_integrations.yaml +++ b/pkg/resources/config/crd/bases/camel.apache.org_integrations.yaml @@ -7781,7 +7781,7 @@ spec: type: object registry: description: |- - The configuration of Registry trait + The configuration of Registry trait (support removed since version 2.5.0). Deprecated: use jvm trait or read documentation. properties: configuration: diff --git a/pkg/resources/config/crd/bases/camel.apache.org_kameletbindings.yaml b/pkg/resources/config/crd/bases/camel.apache.org_kameletbindings.yaml index 1de31c92ee..2805a4bc92 100644 --- a/pkg/resources/config/crd/bases/camel.apache.org_kameletbindings.yaml +++ b/pkg/resources/config/crd/bases/camel.apache.org_kameletbindings.yaml @@ -7854,7 +7854,7 @@ spec: type: object registry: description: |- - The configuration of Registry trait + The configuration of Registry trait (support removed since version 2.5.0). Deprecated: use jvm trait or read documentation. properties: configuration: diff --git a/pkg/resources/config/crd/bases/camel.apache.org_pipes.yaml b/pkg/resources/config/crd/bases/camel.apache.org_pipes.yaml index a3ae76d7c6..77aa04e8e5 100644 --- a/pkg/resources/config/crd/bases/camel.apache.org_pipes.yaml +++ b/pkg/resources/config/crd/bases/camel.apache.org_pipes.yaml @@ -7852,7 +7852,7 @@ spec: type: object registry: description: |- - The configuration of Registry trait + The configuration of Registry trait (support removed since version 2.5.0). Deprecated: use jvm trait or read documentation. properties: configuration: diff --git a/pkg/trait/quarkus.go b/pkg/trait/quarkus.go index 2c4e5e2194..d720db315c 100644 --- a/pkg/trait/quarkus.go +++ b/pkg/trait/quarkus.go @@ -315,8 +315,6 @@ func propagate(traitSource string, traits v1.Traits, kitTraits *v1.IntegrationKi Builder: traits.Builder.DeepCopy(), Camel: traits.Camel.DeepCopy(), Quarkus: traits.Quarkus.DeepCopy(), - - Registry: traits.Registry.DeepCopy(), } if err := kitTraits.Merge(ikt); err != nil { diff --git a/pkg/trait/registry.go b/pkg/trait/registry.go deleted file mode 100644 index 288aef6157..0000000000 --- a/pkg/trait/registry.go +++ /dev/null @@ -1,311 +0,0 @@ -/* -Licensed to the Apache Software Foundation (ASF) under one or more -contributor license agreements. See the NOTICE file distributed with -this work for additional information regarding copyright ownership. -The ASF licenses this file to You 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 trait - -import ( - "encoding/json" - "errors" - "fmt" - "regexp" - "strings" - - base64 "encoding/base64" - - v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" - traitv1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1/trait" - "github.com/apache/camel-k/v2/pkg/platform" - "github.com/apache/camel-k/v2/pkg/util/defaults" - "github.com/apache/camel-k/v2/pkg/util/kubernetes" - "github.com/apache/camel-k/v2/pkg/util/registry" - - corev1 "k8s.io/api/core/v1" - "k8s.io/utils/ptr" - ctrl "sigs.k8s.io/controller-runtime/pkg/client" -) - -const ( - registryTraitID = "registry" - registryTraitOrder = 1650 -) - -type registryTrait struct { - BaseTrait - traitv1.RegistryTrait `property:",squash"` -} - -func newRegistryTrait() Trait { - return ®istryTrait{ - BaseTrait: NewBaseTrait(registryTraitID, registryTraitOrder), - } -} - -// InfluencesKit overrides base class method. -func (t *registryTrait) InfluencesKit() bool { - return true -} - -func (t *registryTrait) Configure(e *Environment) (bool, *TraitCondition, error) { - // disabled by default - if e.IntegrationKit == nil || !ptr.Deref(t.Enabled, false) { - return false, nil, nil - } - enabled := e.IntegrationKitInPhase(v1.IntegrationKitPhaseBuildSubmitted) - if enabled { - condition := NewIntegrationCondition( - "Registry", - v1.IntegrationConditionTraitInfo, - corev1.ConditionTrue, - traitConfigurationReason, - "Registry trait is deprecated. It may be removed in future version. Read documentation to find alternatives (likely JVM trait).", - ) - return true, condition, nil - } - return false, nil, nil -} - -func (t *registryTrait) Apply(e *Environment) error { - registryAddress := e.Platform.Status.Build.Registry.Address - if registryAddress == "" && e.Platform.Status.Cluster == v1.IntegrationPlatformClusterOpenShift { - registryAddress = defaults.OpenShiftRegistryAddress - } - if registryAddress == "" { - return errors.New("could not figure out Image Registry URL, please set it manually") - } - build := getBuilderTask(e.Pipeline) - - registryCa, registrySecret, err := t.getRegistryCaAndSecret(e) - if err != nil { - return err - } - - if registryCa != "" { - err := addImageRegistryCaToMavenBuild(registryCa, build) - if err != nil { - return err - } - } - if registrySecret != "" { - server, err := extractMavenServerCredentialsFromSecret(registrySecret, e, registryAddress) - if err != nil { - return err - } - build.Maven.Servers = append(build.Maven.Servers, server) - } - addRegistryAndExtensionToMaven(registryAddress, build, e.Platform) - return nil -} - -func (t *registryTrait) getRegistryCaAndSecret(e *Environment) (string, string, error) { - registryCa := e.Platform.Status.Build.Registry.CA - registrySecret := e.Platform.Status.Build.Registry.Secret - - if e.Platform.Status.Cluster != v1.IntegrationPlatformClusterOpenShift { - return registryCa, registrySecret, nil - } - - if registryCa == "" { - ca, err := getOpenShiftImageRegistryCA(e) - if err != nil { - return "", "", err - } - registryCa = ca - } - if registrySecret == "" { - secret, err := getOpenShiftRegistrySecret(e) - if err != nil { - return "", "", err - } - registrySecret = secret - } - - return registryCa, registrySecret, nil -} - -func addRegistryAndExtensionToMaven(registryAddress string, build *v1.BuilderTask, platform *v1.IntegrationPlatform) { - organization := platform.Status.Build.Registry.Organization - if organization == "" { - organization = platform.Namespace - } - registryAddress = fmt.Sprintf("%s/%s", registryAddress, organization) - ext := v1.MavenArtifact{ - GroupID: "com.github.johnpoth", - ArtifactID: "wagon-docker-registry", - Version: "0.2.0", - } - policy := v1.RepositoryPolicy{ - Enabled: true, - ChecksumPolicy: "fail", - } - repo := v1.Repository{ - ID: "image-registry", - URL: "docker://" + registryAddress, - Snapshots: policy, - Releases: policy, - } - build.Maven.Repositories = append(build.Maven.Repositories, repo) - build.Maven.Extension = append(build.Maven.Extension, ext) -} - -func getOpenShiftRegistrySecret(e *Environment) (string, error) { - // does not create it if it already exists - err := platform.CreateBuilderServiceAccount(e.Ctx, e.Client, e.Platform) - if err != nil { - return "", err - } - sa := corev1.ServiceAccount{} - key := ctrl.ObjectKey{ - Name: platform.BuilderServiceAccount, - Namespace: e.Platform.Namespace, - } - err = e.Client.Get(e.Ctx, key, &sa) - if err != nil { - return "", err - } - - for _, secret := range sa.Secrets { - if strings.Contains(secret.Name, "camel-k-builder-dockercfg") { - return secret.Name, nil - } - } - return "", nil -} - -func extractMavenServerCredentialsFromSecret(registrySecret string, e *Environment, registryAddress string) (v1.Server, error) { - secret, err := kubernetes.GetSecret(e.Ctx, e.Client, registrySecret, e.Platform.Namespace) - if err != nil { - return v1.Server{}, err - } - if secret.Type == corev1.SecretTypeBasicAuth { - return v1.Server{ - ID: "image-registry", - Username: string(secret.Data[corev1.BasicAuthUsernameKey]), - Password: string(secret.Data[corev1.BasicAuthPasswordKey]), - }, nil - } - - secretData, err := getDockerConfig(secret) - if err != nil { - return v1.Server{}, err - } - dockerAuth := registry.DockerConfigList{} - err = json.Unmarshal(secretData, &dockerAuth) - if err != nil { - return v1.Server{}, err - } - config, ok := dockerAuth.Auths[registryAddress] - if !ok { - return v1.Server{}, fmt.Errorf("cannot resolve registry address %s in secret %s", registryAddress, registrySecret) - } - username := config.Username - password := config.Password - if username == "" && config.Auth != "" { - decoded := base64.StdEncoding.EncodeToString([]byte(config.Auth)) - parts := strings.Split(decoded, ":") - if len(parts) == 2 { - username = strings.Split(decoded, ":")[0] - } - } - if password == "" && config.Auth != "" { - decoded := base64.StdEncoding.EncodeToString([]byte(config.Auth)) - parts := strings.Split(decoded, ":") - if len(parts) == 2 { - password = strings.Split(decoded, ":")[1] - } - } - return v1.Server{ - ID: "image-registry", - Username: username, - Password: password, - }, nil -} - -func getDockerConfig(secret *corev1.Secret) ([]byte, error) { - if secret.Type == corev1.SecretTypeDockerConfigJson { - secretData, ok := secret.Data[corev1.DockerConfigJsonKey] - if !ok { - return nil, fmt.Errorf("cannot convert secret into Docker Config") - } - return secretData, nil - } - if secret.Type == corev1.SecretTypeDockercfg { - secretData, ok := secret.Data[corev1.DockerConfigKey] - if !ok { - return nil, fmt.Errorf("cannot convert secret into Docker config") - } - secretData = []byte(fmt.Sprintf("{ \"auths\": %s}", secretData)) - return secretData, nil - } - return nil, fmt.Errorf("unsupported Secret type %s", secret.Type) -} - -func getOpenShiftImageRegistryCA(e *Environment) (string, error) { - // does not create it if it already exists - err := platform.CreateBuilderServiceAccount(e.Ctx, e.Client, e.Platform) - if err != nil { - return "", err - } - sa := corev1.ServiceAccount{} - key := ctrl.ObjectKey{ - Name: platform.BuilderServiceAccount, - Namespace: e.Platform.Namespace, - } - err = e.Client.Get(e.Ctx, key, &sa) - if err != nil { - return "", err - } - for _, secret := range sa.Secrets { - if strings.Contains(secret.Name, "camel-k-builder-token") { - return secret.Name + "/service-ca.crt", nil - } - } - return "", errors.New("could not find OpenShift Image Registry CA") -} - -func addImageRegistryCaToMavenBuild(registryCa string, build *v1.BuilderTask) error { - secret, err := decodeSecretKeySelector(registryCa) - if err != nil { - return err - } - contains := false - for _, ca := range build.Maven.CASecrets { - if ca.Name == secret.Name && ca.Key == secret.Key { - contains = true - } - } - if !contains { - build.Maven.CASecrets = append(build.Maven.CASecrets, *secret) - } - return nil -} - -func decodeSecretKeySelector(secretKey string) (*corev1.SecretKeySelector, error) { - r := regexp.MustCompile(`^([a-zA-Z0-9-]*)/([a-zA-Z0-9.].*)$`) - - if !r.MatchString(secretKey) { - return nil, fmt.Errorf("illegal Maven CA certificates secret key selector, syntax: secret-name/secret-key") - } - - match := r.FindStringSubmatch(secretKey) - - return &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: match[1], - }, - Key: match[2], - }, nil -} diff --git a/pkg/trait/trait_register.go b/pkg/trait/trait_register.go index 0174bdc3f7..bac29dab51 100644 --- a/pkg/trait/trait_register.go +++ b/pkg/trait/trait_register.go @@ -50,7 +50,6 @@ func init() { AddToTraits(newPrometheusTrait) AddToTraits(newPullSecretTrait) AddToTraits(newQuarkusTrait) - AddToTraits(newRegistryTrait) AddToTraits(newRouteTrait) AddToTraits(newSecurityContextTrait) AddToTraits(newServiceTrait)