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 2020/02/26 18:34:47 UTC
[camel-k] 04/15: feat(buildah): Auto-configure OpenShift internal
registry certificate authority
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 69e73491e9a2d8bca7ed55673eb48bd9d11afd92
Author: Antonin Stefanutti <an...@stefanutti.fr>
AuthorDate: Mon Feb 24 16:21:32 2020 +0100
feat(buildah): Auto-configure OpenShift internal registry certificate authority
---
pkg/apis/camel/v1/integrationplatform_types.go | 1 +
pkg/platform/defaults.go | 26 ++++++++
pkg/trait/builder.go | 84 +++++++++++++++++++++++---
3 files changed, 104 insertions(+), 7 deletions(-)
diff --git a/pkg/apis/camel/v1/integrationplatform_types.go b/pkg/apis/camel/v1/integrationplatform_types.go
index ff9afbb..ad00423 100644
--- a/pkg/apis/camel/v1/integrationplatform_types.go
+++ b/pkg/apis/camel/v1/integrationplatform_types.go
@@ -121,6 +121,7 @@ type IntegrationPlatformRegistrySpec struct {
Insecure bool `json:"insecure,omitempty"`
Address string `json:"address,omitempty"`
Secret string `json:"secret,omitempty"`
+ CA string `json:"ca,omitempty"`
Organization string `json:"organization,omitempty"`
}
diff --git a/pkg/platform/defaults.go b/pkg/platform/defaults.go
index caffed1..e04d3ef 100644
--- a/pkg/platform/defaults.go
+++ b/pkg/platform/defaults.go
@@ -90,6 +90,13 @@ func ConfigureDefaults(ctx context.Context, c client.Client, p *v1.IntegrationPl
p.Status.Build.Registry.Address == "" {
p.Status.Build.Registry.Address = "image-registry.openshift-image-registry.svc:5000"
+ // OpenShift automatically injects the service CA certificate into the service-ca.crt key on the ConfigMap
+ cm, err := createServiceCaBundleConfigMap(ctx, c, p)
+ if err != nil {
+ return err
+ }
+ p.Status.Build.Registry.CA = cm.Name
+
// Default to using the registry secret that's configured for the builder service account
if p.Status.Build.Registry.Secret == "" {
sa := corev1.ServiceAccount{}
@@ -229,3 +236,22 @@ func createDefaultMavenSettingsConfigMap(ctx context.Context, client client.Clie
return nil
}
+
+func createServiceCaBundleConfigMap(ctx context.Context, client client.Client, p *v1.IntegrationPlatform) (*corev1.ConfigMap, error) {
+ cm := &corev1.ConfigMap{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "camel-k-builder-ca",
+ Namespace: p.Namespace,
+ Annotations: map[string]string{
+ "service.beta.openshift.io/inject-cabundle": "true",
+ },
+ },
+ }
+
+ err := client.Create(ctx, cm)
+ if err != nil && !k8serrors.IsAlreadyExists(err) {
+ return nil, err
+ }
+
+ return cm, nil
+}
diff --git a/pkg/trait/builder.go b/pkg/trait/builder.go
index 1a49ee6..72919c8 100644
--- a/pkg/trait/builder.go
+++ b/pkg/trait/builder.go
@@ -211,6 +211,8 @@ func (t *builderTrait) builderTask(e *Environment) *v1.BuilderTask {
func (t *builderTrait) buildahTask(e *Environment) (*v1.ImageTask, error) {
image := getImageName(e)
+ auth := []string{""}
+
bud := []string{
"buildah",
"bud",
@@ -236,15 +238,22 @@ func (t *builderTrait) buildahTask(e *Environment) (*v1.ImageTask, error) {
push = append(push[:2], append([]string{"--log-level=debug"}, push[2:]...)...)
}
- args := []string{
- strings.Join(bud, " "),
- strings.Join(push, " "),
- }
-
env := make([]corev1.EnvVar, 0)
volumes := make([]corev1.Volume, 0)
volumeMounts := make([]corev1.VolumeMount, 0)
+ if e.Platform.Status.Build.Registry.CA != "" {
+ config, err := getRegistryConfigMapFor(e, buildahRegistryConfigMaps)
+ if err != nil {
+ return nil, err
+ }
+ mountRegistryConfigMap(e.Platform.Status.Build.Registry.CA, config, &volumes, &volumeMounts)
+ // This is easier to use the --cert-dir option, otherwise Buildah defaults to looking up certificates
+ //into a directory named after the registry address
+ bud = append(bud[:2], append([]string{"--cert-dir=/etc/containers/certs.d"}, bud[2:]...)...)
+ push = append(push[:2], append([]string{"--cert-dir=/etc/containers/certs.d"}, push[2:]...)...)
+ }
+
if e.Platform.Status.Build.Registry.Secret != "" {
secret, err := getRegistrySecretFor(e, buildahRegistrySecrets)
if err != nil {
@@ -252,10 +261,9 @@ func (t *builderTrait) buildahTask(e *Environment) (*v1.ImageTask, error) {
}
if secret == plainDockerBuildahRegistrySecret {
// Handle old format and make it compatible with Buildah
- auth := []string{
+ auth = []string{
"(echo '{ \"auths\": ' ; cat /buildah/.docker/config.json ; echo \"}\") > /tmp/.dockercfg",
}
- args = append([]string{strings.Join(auth, " ")}, args...)
env = append(env, corev1.EnvVar{
Name: "REGISTRY_AUTH_FILE",
Value: "/tmp/.dockercfg",
@@ -269,6 +277,12 @@ func (t *builderTrait) buildahTask(e *Environment) (*v1.ImageTask, error) {
env = append(env, proxySecretEnvVars(e)...)
+ args := []string{
+ strings.Join(auth, " "),
+ strings.Join(bud, " "),
+ strings.Join(push, " "),
+ }
+
return &v1.ImageTask{
ContainerTask: v1.ContainerTask{
BaseTask: v1.BaseTask{
@@ -384,6 +398,24 @@ var (
}
)
+type registryConfigMap struct {
+ fileName string
+ mountPath string
+ destination string
+}
+
+var (
+ serviceCABuildahRegistryConfigMap = registryConfigMap{
+ fileName: "service-ca.crt",
+ mountPath: "/etc/containers/certs.d",
+ destination: "service-ca.crt",
+ }
+
+ buildahRegistryConfigMaps = []registryConfigMap{
+ serviceCABuildahRegistryConfigMap,
+ }
+)
+
func proxySecretEnvVars(e *Environment) []corev1.EnvVar {
if e.Platform.Status.Build.HTTPProxySecret == "" {
return []corev1.EnvVar{}
@@ -455,6 +487,44 @@ func mountRegistrySecret(name string, secret registrySecret, volumes *[]corev1.V
}
}
+func getRegistryConfigMapFor(e *Environment, registryConfigMaps []registryConfigMap) (registryConfigMap, error) {
+ config := corev1.ConfigMap{}
+ err := e.Client.Get(e.C, client.ObjectKey{Namespace: e.Platform.Namespace, Name: e.Platform.Status.Build.Registry.CA}, &config)
+ if err != nil {
+ return registryConfigMap{}, err
+ }
+ for _, k := range registryConfigMaps {
+ if _, ok := config.Data[k.fileName]; ok {
+ return k, nil
+ }
+ }
+ return registryConfigMap{}, errors.New("unsupported registry config map")
+}
+
+func mountRegistryConfigMap(name string, config registryConfigMap, volumes *[]corev1.Volume, volumeMounts *[]corev1.VolumeMount) {
+ *volumes = append(*volumes, corev1.Volume{
+ Name: "registry-config",
+ VolumeSource: corev1.VolumeSource{
+ ConfigMap: &corev1.ConfigMapVolumeSource{
+ LocalObjectReference: corev1.LocalObjectReference{
+ Name: name,
+ },
+ Items: []corev1.KeyToPath{
+ {
+ Key: config.fileName,
+ Path: config.destination,
+ },
+ },
+ },
+ },
+ })
+
+ *volumeMounts = append(*volumeMounts, corev1.VolumeMount{
+ Name: "registry-config",
+ MountPath: config.mountPath,
+ })
+}
+
func getImageName(e *Environment) string {
organization := e.Platform.Status.Build.Registry.Organization
if organization == "" {