Skip to content

Commit

Permalink
feat: Propagate kubernetes root certificate to che components
Browse files Browse the repository at this point in the history
Signed-off-by: Anatolii Bazko <abazko@redhat.com>
  • Loading branch information
tolusha committed Mar 13, 2023
1 parent 2182f45 commit 13170e8
Show file tree
Hide file tree
Showing 6 changed files with 174 additions and 142 deletions.
38 changes: 0 additions & 38 deletions pkg/common/k8s-helper/k8s_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,9 @@
package k8shelper

import (
"bytes"
"context"
"fmt"
"io"
"os"

corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"k8s.io/apimachinery/pkg/runtime"
Expand All @@ -29,8 +25,6 @@ import (

"github.com/sirupsen/logrus"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/tools/remotecommand"
"sigs.k8s.io/controller-runtime/pkg/client/config"
)

Expand Down Expand Up @@ -77,38 +71,6 @@ func (cl *K8sHelper) GetPodsByComponent(name string, ns string) []string {
return names
}

func (cl *K8sHelper) RunExec(command []string, podName, namespace string, stdin io.Reader) (string, string, error) {
req := cl.clientset.CoreV1().RESTClient().Post().
Resource("pods").
Name(podName).
Namespace(namespace).
SubResource("exec")

req.VersionedParams(&corev1.PodExecOptions{
Command: command,
Stdin: stdin != nil,
Stdout: true,
Stderr: true,
TTY: false,
}, scheme.ParameterCodec)

cfg, _ := config.GetConfig()
exec, err := remotecommand.NewSPDYExecutor(cfg, "POST", req.URL())
if err != nil {
return "", "", fmt.Errorf("error while creating executor: %v", err)
}

var stdout, stderr bytes.Buffer
err = exec.Stream(remotecommand.StreamOptions{
Stdin: stdin,
Stdout: &stdout,
Stderr: &stderr,
Tty: false,
})

return stdout.String(), stderr.String(), err
}

func initializeForTesting() *K8sHelper {
k8sHelper = &K8sHelper{
clientset: fake.NewSimpleClientset(),
Expand Down
16 changes: 16 additions & 0 deletions pkg/deploy/dashboard/dashboard_deployment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,14 @@ func TestDashboardDeploymentEnvVars(t *testing.T) {
Name: "CHE_INTERNAL_URL",
Value: "http://che-host.eclipse-che.svc:8080/api",
},
{
Name: "CHE_WORKSPACE_DEVFILE__REGISTRY__INTERNAL__URL",
Value: "http://devfile-registry.eclipse-che.svc:8080",
},
{
Name: "CHE_WORKSPACE_PLUGIN__REGISTRY__INTERNAL__URL",
Value: "http://plugin-registry.eclipse-che.svc:8080/v3",
},
{
Name: "OPENSHIFT_CONSOLE_URL",
},
Expand Down Expand Up @@ -217,6 +225,14 @@ func TestDashboardDeploymentEnvVars(t *testing.T) {
Name: "CHE_INTERNAL_URL",
Value: "http://che-host.eclipse-che.svc:8080/api",
},
{
Name: "CHE_WORKSPACE_DEVFILE__REGISTRY__INTERNAL__URL",
Value: "http://devfile-registry.eclipse-che.svc:8080",
},
{
Name: "CHE_WORKSPACE_PLUGIN__REGISTRY__INTERNAL__URL",
Value: "http://plugin-registry.eclipse-che.svc:8080/v3",
},
{
Name: "OPENSHIFT_CONSOLE_URL",
Value: "https://console-openshift-console.apps.my-host/",
Expand Down
16 changes: 16 additions & 0 deletions pkg/deploy/dashboard/deployment_dashboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,22 @@ func (d *DashboardReconciler) getDashboardDeploymentSpec(ctx *chetypes.DeployCon
Value: fmt.Sprintf("http://%s.%s.svc:8080/api", deploy.CheServiceName, ctx.CheCluster.Namespace)},
)

if !ctx.CheCluster.Spec.Components.DevfileRegistry.DisableInternalRegistry {
envVars = append(envVars,
corev1.EnvVar{
Name: "CHE_WORKSPACE_DEVFILE__REGISTRY__INTERNAL__URL",
Value: fmt.Sprintf("http://%s.%s.svc:8080", constants.DevfileRegistryName, ctx.CheCluster.Namespace)},
)
}

if !ctx.CheCluster.Spec.Components.PluginRegistry.DisableInternalRegistry {
envVars = append(envVars,
corev1.EnvVar{
Name: "CHE_WORKSPACE_PLUGIN__REGISTRY__INTERNAL__URL",
Value: fmt.Sprintf("http://%s.%s.svc:8080/v3", constants.PluginRegistryName, ctx.CheCluster.Namespace)},
)
}

if utils.IsK8SResourceServed(ctx.ClusterAPI.DiscoveryClient, ConsoleLinksResourceName) {
envVars = append(envVars,
corev1.EnvVar{
Expand Down
66 changes: 57 additions & 9 deletions pkg/deploy/tls/certificates.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ package tls

import (
"context"
k8shelper "github.com/eclipse-che/che-operator/pkg/common/k8s-helper"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/json"
"reflect"
"strings"

Expand All @@ -37,10 +40,12 @@ const (
// CheMergedCAConfigMapRevisionsAnnotationKey is annotation name which holds versions of included config maps in format: cm-name1=ver1,cm-name2=ver2
CheMergedCAConfigMapRevisionsAnnotationKey = "che.eclipse.org/included-configmaps"

KubernetesRootCertificateConfigMapName = "kube-root-ca.crt"

// Local constants
// labelEqualSign consyant is used as a replacement for '=' symbol in labels because '=' is not allowed there
// labelEqualSign constant is used as a replacement for '=' symbol in labels because '=' is not allowed there
labelEqualSign = "-"
// labelCommaSign consyant is used as a replacement for ',' symbol in labels because ',' is not allowed there
// labelCommaSign constant is used as a replacement for ',' symbol in labels because ',' is not allowed there
labelCommaSign = "."
)

Expand All @@ -54,14 +59,20 @@ func NewCertificatesReconciler() *CertificatesReconciler {

func (c *CertificatesReconciler) Reconcile(ctx *chetypes.DeployContext) (reconcile.Result, bool, error) {
if ctx.Proxy.TrustedCAMapName != "" {
done, err := c.syncTrustStoreConfigMapToCluster(ctx)
if !done {
return reconcile.Result{}, done, err
if done, err := c.syncTrustStoreConfigMapToCluster(ctx); !done {
return reconcile.Result{}, false, err
}
}

done, err := c.syncAdditionalCACertsConfigMapToCluster(ctx)
return reconcile.Result{}, done, err
if done, err := c.syncKubernetesRootCertificates(ctx); !done {
return reconcile.Result{}, false, err
}

if done, err := c.syncAdditionalCACertsConfigMapToCluster(ctx); !done {
return reconcile.Result{}, false, err
}

return reconcile.Result{}, true, nil
}

func (c *CertificatesReconciler) Finalize(ctx *chetypes.DeployContext) bool {
Expand Down Expand Up @@ -105,6 +116,44 @@ func (c *CertificatesReconciler) syncTrustStoreConfigMapToCluster(ctx *chetypes.
return true, nil
}

// syncAdditionalCACertsConfigMapToCluster adds labels to ConfigMap `kube-root-ca.crt` to propagate
// Kubernetes root certificates to Che components. It is needed to use NonCachingClient because the map
// initially is not in the cache.
func (c *CertificatesReconciler) syncKubernetesRootCertificates(ctx *chetypes.DeployContext) (bool, error) {
certs := &corev1.ConfigMap{}
if err := ctx.ClusterAPI.NonCachingClient.Get(
context.TODO(),
types.NamespacedName{
Name: KubernetesRootCertificateConfigMapName,
Namespace: ctx.CheCluster.Namespace,
},
certs); err != nil {
if errors.IsNotFound(err) {
return true, nil
} else {
return false, err
}
}

patchData, _ := json.Marshal(corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{
constants.KubernetesPartOfLabelKey: constants.CheEclipseOrg,
constants.KubernetesComponentLabelKey: CheCACertsConfigMapLabelValue,
},
},
})

_, err := k8shelper.New().GetClientset().CoreV1().ConfigMaps(ctx.CheCluster.Namespace).Patch(
context.TODO(),
KubernetesRootCertificateConfigMapName,
types.MergePatchType,
patchData,
metav1.PatchOptions{},
)
return err == nil, err
}

func (c *CertificatesReconciler) syncAdditionalCACertsConfigMapToCluster(ctx *chetypes.DeployContext) (bool, error) {
// Get all source config maps, if any
caConfigMaps, err := GetCACertsConfigMaps(ctx.ClusterAPI.Client, ctx.CheCluster.GetNamespace())
Expand Down Expand Up @@ -182,6 +231,5 @@ func (c *CertificatesReconciler) syncAdditionalCACertsConfigMapToCluster(ctx *ch
mergedCAConfigMapSpec := deploy.GetConfigMapSpec(ctx, CheAllCACertsConfigMapName, data, defaults.GetCheFlavor())
mergedCAConfigMapSpec.ObjectMeta.Labels[constants.KubernetesPartOfLabelKey] = constants.CheEclipseOrg
mergedCAConfigMapSpec.ObjectMeta.Annotations[CheMergedCAConfigMapRevisionsAnnotationKey] = revisions
done, err := deploy.SyncConfigMapSpecToCluster(ctx, mergedCAConfigMapSpec)
return done, err
return deploy.SyncConfigMapSpecToCluster(ctx, mergedCAConfigMapSpec)
}
4 changes: 2 additions & 2 deletions pkg/deploy/tls/tls_secret.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func (t *TlsSecretReconciler) Reconcile(ctx *chetypes.DeployContext) (reconcile.
if infrastructure.IsOpenShift() {
// create a secret with router tls cert when on OpenShift infra and router is configured with a self signed certificate
if ctx.IsSelfSignedCertificate {
if err := CreateTLSSecretFromEndpoint(ctx, "", constants.DefaultSelfSignedCertificateSecretName); err != nil {
if err := CreateTLSSecret(ctx, constants.DefaultSelfSignedCertificateSecretName); err != nil {
return reconcile.Result{}, false, err
}
}
Expand All @@ -46,7 +46,7 @@ func (t *TlsSecretReconciler) Reconcile(ctx *chetypes.DeployContext) (reconcile.
}
} else if ctx.IsSelfSignedCertificate {
// Use default self-signed ingress certificate
if err := CreateTLSSecretFromEndpoint(ctx, "", constants.DefaultSelfSignedCertificateSecretName); err != nil {
if err := CreateTLSSecret(ctx, constants.DefaultSelfSignedCertificateSecretName); err != nil {
return reconcile.Result{}, false, err
}
}
Expand Down
Loading

0 comments on commit 13170e8

Please sign in to comment.