You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by as...@apache.org on 2021/03/30 17:20:43 UTC
[camel-k] 01/20: feat(build): Add CA cert from user Secret into
Maven build JVM trust store
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 <an...@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"`
}
-
-