This is an automated email from the ASF dual-hosted git repository.

astefanutti pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit e913ccf5a26c783ca843f527240433c0c98043e9
Author: Antonin Stefanutti <anto...@stefanutti.fr>
AuthorDate: Mon Mar 22 15:57:54 2021 +0100

    feat(build): Add CA cert from user Secret into Maven build JVM trust store
---
 pkg/apis/camel/v1/common_types.go  |  7 ++---
 pkg/builder/project.go             | 36 +++++++++++++++++++++++++-
 pkg/builder/quarkus.go             |  4 +++
 pkg/builder/types.go               |  5 ++--
 pkg/trait/quarkus_test.go          |  2 +-
 pkg/util/kubernetes/core_client.go | 52 +++++++++++++++++++++++---------------
 pkg/util/kubernetes/util.go        |  2 --
 pkg/util/maven/maven.go            | 25 +++++++++++++++---
 pkg/util/maven/maven_types.go      | 11 ++++----
 9 files changed, 104 insertions(+), 40 deletions(-)

diff --git a/pkg/apis/camel/v1/common_types.go 
b/pkg/apis/camel/v1/common_types.go
index d772e77..ae0413b 100644
--- a/pkg/apis/camel/v1/common_types.go
+++ b/pkg/apis/camel/v1/common_types.go
@@ -83,9 +83,10 @@ type PlatformInjectable interface {
 
 // MavenSpec --
 type MavenSpec struct {
-       LocalRepository string           `json:"localRepository,omitempty"`
-       Settings        ValueSource      `json:"settings,omitempty"`
-       Timeout         *metav1.Duration `json:"timeout,omitempty"`
+       LocalRepository string                    
`json:"localRepository,omitempty"`
+       Settings        ValueSource               `json:"settings,omitempty"`
+       CaCert          *corev1.SecretKeySelector `json:"caCert,omitempty"`
+       Timeout         *metav1.Duration          `json:"timeout,omitempty"`
 }
 
 // ValueSource --
diff --git a/pkg/builder/project.go b/pkg/builder/project.go
index 1bd363f..27e20fe 100644
--- a/pkg/builder/project.go
+++ b/pkg/builder/project.go
@@ -18,19 +18,24 @@ limitations under the License.
 package builder
 
 import (
+       "fmt"
        "os"
+       "os/exec"
+       "path"
+       "strings"
 
+       "github.com/apache/camel-k/pkg/util"
        "github.com/apache/camel-k/pkg/util/camel"
        "github.com/apache/camel-k/pkg/util/kubernetes"
 )
 
-
 func init() {
        registerSteps(Steps)
 }
 
 type steps struct {
        CleanUpBuildDir         Step
+       GenerateJavaKeystore    Step
        GenerateProjectSettings Step
        InjectDependencies      Step
        SanitizeDependencies    Step
@@ -40,6 +45,7 @@ type steps struct {
 
 var Steps = steps{
        CleanUpBuildDir:         NewStep(ProjectGenerationPhase-1, 
cleanUpBuildDir),
+       GenerateJavaKeystore:    NewStep(ProjectGenerationPhase, 
generateJavaKeystore),
        GenerateProjectSettings: NewStep(ProjectGenerationPhase+1, 
generateProjectSettings),
        InjectDependencies:      NewStep(ProjectGenerationPhase+2, 
injectDependencies),
        SanitizeDependencies:    NewStep(ProjectGenerationPhase+3, 
sanitizeDependencies),
@@ -49,6 +55,7 @@ var Steps = steps{
 
 var DefaultSteps = []Step{
        Steps.CleanUpBuildDir,
+       Steps.GenerateJavaKeystore,
        Steps.GenerateProjectSettings,
        Steps.InjectDependencies,
        Steps.SanitizeDependencies,
@@ -63,6 +70,33 @@ func cleanUpBuildDir(ctx *builderContext) error {
        return os.RemoveAll(ctx.Build.BuildDir)
 }
 
+func generateJavaKeystore(ctx *builderContext) error {
+       if ctx.Build.Maven.CaCert == nil {
+               return nil
+       }
+
+       certData, err := kubernetes.GetSecretRefData(ctx.C, ctx.Client, 
ctx.Namespace, ctx.Build.Maven.CaCert)
+       if err != nil {
+               return err
+       }
+
+       certPath := ctx.Build.Maven.CaCert.Key
+       if err := util.WriteFileWithContent(ctx.Path, certPath, certData); err 
!= nil {
+               return err
+       }
+
+       keystore := "trust.jks"
+       ctx.Maven.TrustStorePath = path.Join(ctx.Path, keystore)
+
+       args := strings.Fields(fmt.Sprintf("-importcert -alias maven -file %s 
-keystore %s", certPath, keystore))
+       cmd := exec.CommandContext(ctx.C, "keytool", args...)
+       cmd.Dir = ctx.Path
+       cmd.Stderr = os.Stderr
+       cmd.Stdout = os.Stdout
+
+       return cmd.Run()
+}
+
 func generateProjectSettings(ctx *builderContext) error {
        val, err := kubernetes.ResolveValueSource(ctx.C, ctx.Client, 
ctx.Namespace, &ctx.Build.Maven.Settings)
        if err != nil {
diff --git a/pkg/builder/quarkus.go b/pkg/builder/quarkus.go
index 23ef90a..028b919 100644
--- a/pkg/builder/quarkus.go
+++ b/pkg/builder/quarkus.go
@@ -147,6 +147,10 @@ func buildQuarkusRunner(ctx *builderContext) error {
        mc.LocalRepository = ctx.Build.Maven.LocalRepository
        mc.Timeout = ctx.Build.Maven.GetTimeout().Duration
 
+       if ctx.Maven.TrustStorePath != "" {
+               mc.ExtraMavenOpts = append(mc.ExtraMavenOpts, 
"-Djavax.net.ssl.trustStore="+path.Join(ctx.Path, ctx.Maven.TrustStorePath))
+       }
+
        err := BuildQuarkusRunnerCommon(mc)
        if err != nil {
                return err
diff --git a/pkg/builder/types.go b/pkg/builder/types.go
index 471ab88..776e8a0 100644
--- a/pkg/builder/types.go
+++ b/pkg/builder/types.go
@@ -88,7 +88,8 @@ type builderContext struct {
        SelectedArtifacts []v1.Artifact
        Resources         []resource
        Maven             struct {
-               Project      maven.Project
-               SettingsData []byte
+               Project        maven.Project
+               SettingsData   []byte
+               TrustStorePath string
        }
 }
diff --git a/pkg/trait/quarkus_test.go b/pkg/trait/quarkus_test.go
index 9061f57..181ba78 100644
--- a/pkg/trait/quarkus_test.go
+++ b/pkg/trait/quarkus_test.go
@@ -62,7 +62,7 @@ func TestQuarkusTraitAddBuildStepsShouldSucceed(t *testing.T) 
{
 
        quarkusTrait.addBuildSteps(&steps)
 
-       assert.Len(t, steps, 9)
+       assert.Len(t, steps, 
len(builder.DefaultSteps)+len(builder.QuarkusSteps))
 }
 
 func createNominalQuarkusTest() (*quarkusTrait, *Environment) {
diff --git a/pkg/util/kubernetes/core_client.go 
b/pkg/util/kubernetes/core_client.go
index 822b209..621a90f 100644
--- a/pkg/util/kubernetes/core_client.go
+++ b/pkg/util/kubernetes/core_client.go
@@ -23,15 +23,16 @@ import (
 
        corev1 "k8s.io/api/core/v1"
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-       k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
+
+       ctrl "sigs.k8s.io/controller-runtime/pkg/client"
 
        v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
        "github.com/apache/camel-k/pkg/client"
 )
 
 // GetIntegrationPlatform --
-func GetIntegrationPlatform(context context.Context, client k8sclient.Reader, 
name string, namespace string) (*v1.IntegrationPlatform, error) {
-       key := k8sclient.ObjectKey{
+func GetIntegrationPlatform(context context.Context, client ctrl.Reader, name 
string, namespace string) (*v1.IntegrationPlatform, error) {
+       key := ctrl.ObjectKey{
                Name:      name,
                Namespace: namespace,
        }
@@ -46,8 +47,8 @@ func GetIntegrationPlatform(context context.Context, client 
k8sclient.Reader, na
 }
 
 // GetIntegrationKit --
-func GetIntegrationKit(context context.Context, client k8sclient.Reader, name 
string, namespace string) (*v1.IntegrationKit, error) {
-       key := k8sclient.ObjectKey{
+func GetIntegrationKit(context context.Context, client ctrl.Reader, name 
string, namespace string) (*v1.IntegrationKit, error) {
+       key := ctrl.ObjectKey{
                Name:      name,
                Namespace: namespace,
        }
@@ -62,8 +63,8 @@ func GetIntegrationKit(context context.Context, client 
k8sclient.Reader, name st
 }
 
 // GetIntegration --
-func GetIntegration(context context.Context, client k8sclient.Reader, name 
string, namespace string) (*v1.Integration, error) {
-       key := k8sclient.ObjectKey{
+func GetIntegration(context context.Context, client ctrl.Reader, name string, 
namespace string) (*v1.Integration, error) {
+       key := ctrl.ObjectKey{
                Name:      name,
                Namespace: namespace,
        }
@@ -79,7 +80,7 @@ func GetIntegration(context context.Context, client 
k8sclient.Reader, name strin
 
 // GetBuild --
 func GetBuild(context context.Context, client client.Client, name string, 
namespace string) (*v1.Build, error) {
-       key := k8sclient.ObjectKey{
+       key := ctrl.ObjectKey{
                Name:      name,
                Namespace: namespace,
        }
@@ -94,8 +95,8 @@ func GetBuild(context context.Context, client client.Client, 
name string, namesp
 }
 
 // GetConfigMap --
-func GetConfigMap(context context.Context, client k8sclient.Reader, name 
string, namespace string) (*corev1.ConfigMap, error) {
-       key := k8sclient.ObjectKey{
+func GetConfigMap(context context.Context, client ctrl.Reader, name string, 
namespace string) (*corev1.ConfigMap, error) {
+       key := ctrl.ObjectKey{
                Name:      name,
                Namespace: namespace,
        }
@@ -119,8 +120,8 @@ func GetConfigMap(context context.Context, client 
k8sclient.Reader, name string,
 }
 
 // GetSecret --
-func GetSecret(context context.Context, client k8sclient.Reader, name string, 
namespace string) (*corev1.Secret, error) {
-       key := k8sclient.ObjectKey{
+func GetSecret(context context.Context, client ctrl.Reader, name string, 
namespace string) (*corev1.Secret, error) {
+       key := ctrl.ObjectKey{
                Name:      name,
                Namespace: namespace,
        }
@@ -144,8 +145,8 @@ func GetSecret(context context.Context, client 
k8sclient.Reader, name string, na
 }
 
 // GetService --
-func GetService(context context.Context, client k8sclient.Reader, name string, 
namespace string) (*corev1.Service, error) {
-       key := k8sclient.ObjectKey{
+func GetService(context context.Context, client ctrl.Reader, name string, 
namespace string) (*corev1.Service, error) {
+       key := ctrl.ObjectKey{
                Name:      name,
                Namespace: namespace,
        }
@@ -168,22 +169,31 @@ func GetService(context context.Context, client 
k8sclient.Reader, name string, n
        return &answer, nil
 }
 
-// GetSecretRefValue returns the value of a secret in the supplied namespace --
-func GetSecretRefValue(ctx context.Context, client k8sclient.Reader, namespace 
string, selector *corev1.SecretKeySelector) (string, error) {
-       secret, err := GetSecret(ctx, client, selector.Name, namespace)
+// GetSecretRefValue returns the value of a secret in the supplied namespace
+func GetSecretRefValue(ctx context.Context, client ctrl.Reader, namespace 
string, selector *corev1.SecretKeySelector) (string, error) {
+       data, err := GetSecretRefData(ctx, client, namespace, selector)
        if err != nil {
                return "", err
        }
+       return string(data), nil
+}
+
+// GetSecretRefData returns the value of a secret in the supplied namespace
+func GetSecretRefData(ctx context.Context, client ctrl.Reader, namespace 
string, selector *corev1.SecretKeySelector) ([]byte, error) {
+       secret, err := GetSecret(ctx, client, selector.Name, namespace)
+       if err != nil {
+               return nil, err
+       }
 
        if data, ok := secret.Data[selector.Key]; ok {
-               return string(data), nil
+               return data, nil
        }
 
-       return "", fmt.Errorf("key %s not found in secret %s", selector.Key, 
selector.Name)
+       return nil, fmt.Errorf("key %s not found in secret %s", selector.Key, 
selector.Name)
 }
 
 // GetConfigMapRefValue returns the value of a configmap in the supplied 
namespace
-func GetConfigMapRefValue(ctx context.Context, client k8sclient.Reader, 
namespace string, selector *corev1.ConfigMapKeySelector) (string, error) {
+func GetConfigMapRefValue(ctx context.Context, client ctrl.Reader, namespace 
string, selector *corev1.ConfigMapKeySelector) (string, error) {
        cm, err := GetConfigMap(ctx, client, selector.Name, namespace)
        if err != nil {
                return "", err
@@ -197,7 +207,7 @@ func GetConfigMapRefValue(ctx context.Context, client 
k8sclient.Reader, namespac
 }
 
 // ResolveValueSource --
-func ResolveValueSource(ctx context.Context, client k8sclient.Reader, 
namespace string, valueSource *v1.ValueSource) (string, error) {
+func ResolveValueSource(ctx context.Context, client ctrl.Reader, namespace 
string, valueSource *v1.ValueSource) (string, error) {
        if valueSource.ConfigMapKeyRef != nil && valueSource.SecretKeyRef != 
nil {
                return "", fmt.Errorf("value source has bot config map and 
secret configured")
        }
diff --git a/pkg/util/kubernetes/util.go b/pkg/util/kubernetes/util.go
index 23d3401..232cf85 100644
--- a/pkg/util/kubernetes/util.go
+++ b/pkg/util/kubernetes/util.go
@@ -24,12 +24,10 @@ import (
        "github.com/apache/camel-k/pkg/util"
 )
 
-// ToJSON --
 func ToJSON(value runtime.Object) ([]byte, error) {
        return json.Marshal(value)
 }
 
-// ToYAML --
 func ToYAML(value runtime.Object) ([]byte, error) {
        data, err := ToJSON(value)
        if err != nil {
diff --git a/pkg/util/maven/maven.go b/pkg/util/maven/maven.go
index 067feca..f49658f 100644
--- a/pkg/util/maven/maven.go
+++ b/pkg/util/maven/maven.go
@@ -35,10 +35,8 @@ import (
        "github.com/apache/camel-k/pkg/util/log"
 )
 
-// Log --
 var Log = log.WithName("maven")
 
-// GenerateProjectStructure --
 func GenerateProjectStructure(context Context) error {
        if err := util.WriteFileWithBytesMarshallerContent(context.Path, 
"pom.xml", context.Project); err != nil {
                return err
@@ -78,7 +76,6 @@ func GenerateProjectStructure(context Context) error {
        return nil
 }
 
-// Run --
 func Run(ctx Context) error {
        if err := GenerateProjectStructure(ctx); err != nil {
                return err
@@ -127,7 +124,27 @@ func Run(ctx Context) error {
                cmd.Stdout = os.Stdout
        }
 
-       Log.WithValues("timeout", timeout.String()).Infof("executing: %s", 
strings.Join(cmd.Args, " "))
+       mavenOpts, ok := os.LookupEnv("MAVEN_OPTS")
+       // FIXME: do not override duplicated Maven options
+       mavenOpts = strings.Join(append(strings.Fields(mavenOpts), 
ctx.ExtraMavenOpts...), " ")
+
+       // Inherit the parent process environment
+       env := os.Environ()
+       if !ok {
+               env = append(env, mavenOpts)
+       } else {
+               for i, e := range env {
+                       if strings.HasPrefix(e, "MAVEN_OPTS=") {
+                               env[i] = mavenOpts
+                               break
+                       }
+               }
+       }
+
+       cmd.Env = env
+
+       Log.WithValues("timeout", timeout.String(), "env", env).
+               Infof("executing: %s", strings.Join(cmd.Args, " "))
 
        return cmd.Run()
 }
diff --git a/pkg/util/maven/maven_types.go b/pkg/util/maven/maven_types.go
index 3b7dba5..3bac740 100644
--- a/pkg/util/maven/maven_types.go
+++ b/pkg/util/maven/maven_types.go
@@ -43,10 +43,10 @@ type RepositoryPolicy struct {
 
 // Mirror --
 type Mirror struct {
-       ID        string           `xml:"id"`
-       Name      string           `xml:"name,omitempty"`
-       URL       string           `xml:"url"`
-       MirrorOf  string           `xml:"mirrorOf"`
+       ID       string `xml:"id"`
+       Name     string `xml:"name,omitempty"`
+       URL      string `xml:"url"`
+       MirrorOf string `xml:"mirrorOf"`
 }
 
 // Build --
@@ -120,6 +120,7 @@ func NewContext(buildDir string, project Project) Context {
 type Context struct {
        Path                string
        Project             Project
+       ExtraMavenOpts      []string
        SettingsContent     []byte
        AdditionalArguments []string
        AdditionalEntries   map[string]interface{}
@@ -244,5 +245,3 @@ type PropertyActivation struct {
        Name  string `xml:"name"`
        Value string `xml:"value"`
 }
-
-

Reply via email to