Skip to content

Commit

Permalink
Inject CA trust bundle into managed containers and set SSL_CERT_DIR
Browse files Browse the repository at this point in the history
  • Loading branch information
osmman committed Jul 3, 2024
1 parent d0881cf commit 1a2354b
Show file tree
Hide file tree
Showing 19 changed files with 506 additions and 73 deletions.
24 changes: 12 additions & 12 deletions api/v1alpha1/rekor_types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ package v1alpha1
import (
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/securesign/operator/internal/controller/common/utils"
"golang.org/x/net/context"
_ "k8s.io/api/apps/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
k8sresource "k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/utils/pointer"
)

var _ = Describe("Rekor", func() {
Expand Down Expand Up @@ -77,27 +77,27 @@ var _ = Describe("Rekor", func() {
When("changing Rekor Search UI", func() {
It("enabled false->true", func() {
created := generateRekorObject("rekor-ui-1")
created.Spec.RekorSearchUI.Enabled = utils.Pointer(false)
created.Spec.RekorSearchUI.Enabled = pointer.Bool(false)
Expect(k8sClient.Create(context.Background(), created)).To(Succeed())

fetched := &Rekor{}
Expect(k8sClient.Get(context.Background(), getKey(created), fetched)).To(Succeed())
Expect(fetched).To(Equal(created))

fetched.Spec.RekorSearchUI.Enabled = utils.Pointer(true)
fetched.Spec.RekorSearchUI.Enabled = pointer.Bool(true)
Expect(k8sClient.Update(context.Background(), fetched)).To(Succeed())
})

It("enabled true->false", func() {
created := generateRekorObject("rekor-ui-2")
created.Spec.RekorSearchUI.Enabled = utils.Pointer(true)
created.Spec.RekorSearchUI.Enabled = pointer.Bool(true)
Expect(k8sClient.Create(context.Background(), created)).To(Succeed())

fetched := &Rekor{}
Expect(k8sClient.Get(context.Background(), getKey(created), fetched)).To(Succeed())
Expect(fetched).To(Equal(created))

fetched.Spec.RekorSearchUI.Enabled = utils.Pointer(false)
fetched.Spec.RekorSearchUI.Enabled = pointer.Bool(false)
Expect(apierrors.IsInvalid(k8sClient.Update(context.Background(), fetched))).To(BeTrue())
Expect(k8sClient.Update(context.Background(), fetched)).
To(MatchError(ContainSubstring("Feature cannot be disabled")))
Expand Down Expand Up @@ -150,7 +150,7 @@ var _ = Describe("Rekor", func() {

invalidObject := &Rekor{}
Expect(k8sClient.Get(context.Background(), getKey(validObject), invalidObject)).To(Succeed())
invalidObject.Spec.Pvc.Retain = utils.Pointer(false)
invalidObject.Spec.Pvc.Retain = pointer.Bool(false)

Expect(apierrors.IsInvalid(k8sClient.Update(context.Background(), invalidObject))).To(BeTrue())
Expect(k8sClient.Update(context.Background(), invalidObject)).
Expand Down Expand Up @@ -214,18 +214,18 @@ var _ = Describe("Rekor", func() {
Host: "hostname",
},
RekorSearchUI: RekorSearchUI{
Enabled: utils.Pointer(true),
Enabled: pointer.Bool(true),
},
BackFillRedis: BackFillRedis{
Enabled: utils.Pointer(true),
Enabled: pointer.Bool(true),
Schedule: "* */2 * * 0-3",
},
TreeID: &tree,
Pvc: Pvc{
Name: "name",
Size: &storage,
StorageClass: "name",
Retain: utils.Pointer(true),
Retain: pointer.Bool(true),
},
Signer: RekorSigner{
KMS: "secret",
Expand Down Expand Up @@ -294,18 +294,18 @@ func generateRekorObject(name string) *Rekor {
},
Spec: RekorSpec{
BackFillRedis: BackFillRedis{
Enabled: utils.Pointer(true),
Enabled: pointer.Bool(true),
Schedule: "0 0 * * *",
},
Signer: RekorSigner{
KMS: "secret",
},
Pvc: Pvc{
Retain: utils.Pointer(true),
Retain: pointer.Bool(true),
Size: &storage,
},
Trillian: TrillianService{
Port: utils.Pointer(int32(8091)),
Port: pointer.Int32(int32(8091)),
},
},
}
Expand Down
18 changes: 9 additions & 9 deletions api/v1alpha1/trillian_types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ package v1alpha1
import (
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/securesign/operator/internal/controller/common/utils"
"golang.org/x/net/context"
_ "k8s.io/api/apps/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
k8sresource "k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/utils/pointer"
)

var _ = Describe("Trillian", func() {
Expand Down Expand Up @@ -58,7 +58,7 @@ var _ = Describe("Trillian", func() {

invalidObject := &Trillian{}
Expect(k8sClient.Get(context.Background(), getKey(validObject), invalidObject)).To(Succeed())
invalidObject.Spec.Db.Create = utils.Pointer(false)
invalidObject.Spec.Db.Create = pointer.Bool(false)

Expect(apierrors.IsInvalid(k8sClient.Update(context.Background(), invalidObject))).To(BeTrue())
Expect(k8sClient.Update(context.Background(), invalidObject)).
Expand All @@ -71,7 +71,7 @@ var _ = Describe("Trillian", func() {

invalidObject := &Trillian{}
Expect(k8sClient.Get(context.Background(), getKey(validObject), invalidObject)).To(Succeed())
invalidObject.Spec.Db.Pvc.Retain = utils.Pointer(false)
invalidObject.Spec.Db.Pvc.Retain = pointer.Bool(false)

Expect(apierrors.IsInvalid(k8sClient.Update(context.Background(), invalidObject))).To(BeTrue())
Expect(k8sClient.Update(context.Background(), invalidObject)).
Expand All @@ -82,7 +82,7 @@ var _ = Describe("Trillian", func() {
It("true", func() {
By("databaseSecretRef is empty", func() {
validObject := generateTrillianObject("database-secret-1")
validObject.Spec.Db.Create = utils.Pointer(true)
validObject.Spec.Db.Create = pointer.Bool(true)
validObject.Spec.Db.DatabaseSecretRef = nil
Expect(k8sClient.Create(context.Background(), validObject)).To(Succeed())
})
Expand All @@ -91,7 +91,7 @@ var _ = Describe("Trillian", func() {
It("false", func() {
By("databaseSecretRef is mandatory", func() {
invalidObject := generateTrillianObject("database-secret-2")
invalidObject.Spec.Db.Create = utils.Pointer(false)
invalidObject.Spec.Db.Create = pointer.Bool(false)
invalidObject.Spec.Db.DatabaseSecretRef = nil
Expect(apierrors.IsInvalid(k8sClient.Create(context.Background(), invalidObject))).To(BeTrue())
Expect(k8sClient.Create(context.Background(), invalidObject)).
Expand Down Expand Up @@ -146,9 +146,9 @@ var _ = Describe("Trillian", func() {
},
Spec: TrillianSpec{
Db: TrillianDB{
Create: utils.Pointer(true),
Create: pointer.Bool(true),
Pvc: Pvc{
Retain: utils.Pointer(true),
Retain: pointer.Bool(true),
Name: "storage",
StorageClass: "storage-class",
Size: &storage,
Expand Down Expand Up @@ -208,9 +208,9 @@ func generateTrillianObject(name string) *Trillian {
},
Spec: TrillianSpec{
Db: TrillianDB{
Create: utils.Pointer(true),
Create: pointer.Bool(true),
Pvc: Pvc{
Retain: utils.Pointer(true),
Retain: pointer.Bool(true),
Size: &storage,
},
},
Expand Down
19 changes: 19 additions & 0 deletions internal/controller/annotations/annotations.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,23 @@ const (

// Metrics Annotation is used to control the sending of analytic metrics of the installed services managed by the operator.
Metrics = "rhtas.redhat.com/metrics"

// TrustedCA Annotation to specify name of ConfigMap with additional bundle of trusted CA
TrustedCA = "rhtas.redhat.com/trusted-ca"
)

var inheritable = []string{
TrustedCA,
}

func FilterInheritable(annotations map[string]string) map[string]string {
result := make(map[string]string, 0)
for key, value := range annotations {
for _, ia := range inheritable {
if key == ia {
result[key] = value
}
}
}
return result
}
78 changes: 78 additions & 0 deletions internal/controller/annotations/annotations_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package annotations

import (
"maps"
"reflect"
"strconv"
"testing"
)

func TestFilterInheritable(t *testing.T) {
allIn := make(map[string]string)
allCopy := make(map[string]string)
for i, a := range inheritable {
allIn[a] = strconv.FormatInt(int64(i), 10)
}
maps.Copy(allCopy, allIn)

type args struct {
annotations map[string]string
}
tests := []struct {
name string
args args
want map[string]string
}{
{
name: "empty",
args: args{
annotations: make(map[string]string),
},
want: map[string]string{},
},
{
name: "nil",
args: args{
annotations: nil,
},
want: map[string]string{},
},
{
name: "no inheritable",
args: args{
annotations: map[string]string{
"name1": "value",
"name2": "value",
},
},
want: map[string]string{},
},
{
name: "all inheritable",
args: args{
annotations: allIn,
},
want: allCopy,
},
{
name: "one inheritable",
args: args{
annotations: map[string]string{
"name1": "value",
"name2": "value",
TrustedCA: "ca",
},
},
want: map[string]string{
TrustedCA: "ca",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := FilterInheritable(tt.args.annotations); !reflect.DeepEqual(got, tt.want) {
t.Errorf("FilterInheritable() = %v, want %v", got, tt.want)
}
})
}
}
68 changes: 68 additions & 0 deletions internal/controller/common/utils/set_trusted_ca.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package utils

import (
"errors"
"github.com/securesign/operator/api/v1alpha1"
"github.com/securesign/operator/internal/controller/annotations"
corev1 "k8s.io/api/core/v1"
)

// SetTrustedCA mount config map with trusted CA bundle to all deployment's containers.
func SetTrustedCA(template *corev1.PodTemplateSpec, lor *v1alpha1.LocalObjectReference) error {
if template == nil {
return errors.New("SetTrustedCA: PodTemplateSpec is not set")
}

for i, container := range template.Spec.Containers {
if template.Spec.Containers[i].Env == nil {
template.Spec.Containers[i].Env = make([]corev1.EnvVar, 0)
}
template.Spec.Containers[i].Env = append(container.Env, corev1.EnvVar{
Name: "SSL_CERT_DIR",
Value: "/var/run/configs/tas/ca-trust:/var/run/secrets/kubernetes.io/serviceaccount",
})

if template.Spec.Containers[i].VolumeMounts == nil {
template.Spec.Containers[i].VolumeMounts = make([]corev1.VolumeMount, 0)
}
template.Spec.Containers[i].VolumeMounts = append(container.VolumeMounts, corev1.VolumeMount{
Name: "ca-trust",
MountPath: "/var/run/configs/tas/ca-trust",
ReadOnly: true,
})
}

projections := make([]corev1.VolumeProjection, 0)
if lor != nil {
projections = append(projections, corev1.VolumeProjection{
ConfigMap: &corev1.ConfigMapProjection{
LocalObjectReference: corev1.LocalObjectReference{
Name: lor.Name,
},
},
})
}

if template.Spec.Volumes == nil {
template.Spec.Volumes = make([]corev1.Volume, 0)
}
template.Spec.Volumes = append(template.Spec.Volumes, corev1.Volume{
Name: "ca-trust",
VolumeSource: corev1.VolumeSource{
Projected: &corev1.ProjectedVolumeSource{
Sources: projections,
DefaultMode: Pointer(int32(420)),
},
},
})
return nil
}

func TrustedCAAnnotationToReference(anns map[string]string) *v1alpha1.LocalObjectReference {
if v, ok := anns[annotations.TrustedCA]; ok {
return &v1alpha1.LocalObjectReference{
Name: v,
}
}
return nil
}
Loading

0 comments on commit 1a2354b

Please sign in to comment.