Skip to content

Commit

Permalink
feat: Configure TLS for vm-console-proxy
Browse files Browse the repository at this point in the history
The TLS for vm-console-proxy can be configured
in the ConfigMap that the project reads.

This commit writes a configuration file to the ConfigMap
based on the TLS configuration in the SSP object.

Signed-off-by: Andrej Krejcir <akrejcir@redhat.com>
  • Loading branch information
akrejcir committed Nov 20, 2024
1 parent 3d9461a commit 64a8480
Show file tree
Hide file tree
Showing 8 changed files with 330 additions and 0 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ require (
kubevirt.io/controller-lifecycle-operator-sdk/api v0.2.4
kubevirt.io/qe-tools v0.1.8
kubevirt.io/ssp-operator/api v0.0.0
kubevirt.io/vm-console-proxy/api v0.7.0
sigs.k8s.io/controller-runtime v0.18.5
sigs.k8s.io/yaml v1.4.0
)
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -843,6 +843,8 @@ kubevirt.io/controller-lifecycle-operator-sdk/api v0.2.4 h1:fZYvD3/Vnitfkx6IJxjL
kubevirt.io/controller-lifecycle-operator-sdk/api v0.2.4/go.mod h1:018lASpFYBsYN6XwmA2TIrPCx6e0gviTd/ZNtSitKgc=
kubevirt.io/qe-tools v0.1.8 h1:Ar7qicmzHdd+Ia+6rjHDg3D7GReIyq7QFXoC4F7TjhQ=
kubevirt.io/qe-tools v0.1.8/go.mod h1:+Tr/WZGHIDQa/4pQgzM7+4J6YeVbUWAXESXtL2/zxqc=
kubevirt.io/vm-console-proxy/api v0.7.0 h1:yhzTtywJDqDx3ddIDhuMmN9O19EdGZS0NDqtGwEwk9c=
kubevirt.io/vm-console-proxy/api v0.7.0/go.mod h1:7q967W73c6/Iczl3xJkOjQOASAJ2wXBTEbCbiqD9bXE=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
Expand Down
58 changes: 58 additions & 0 deletions internal/operands/vm-console-proxy/reconcile.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,18 @@ import (
"context"
"fmt"

ocpv1 "github.com/openshift/api/config/v1"
routev1 "github.com/openshift/api/route/v1"
"github.com/openshift/library-go/pkg/crypto"
apps "k8s.io/api/apps/v1"
core "k8s.io/api/core/v1"
rbac "k8s.io/api/rbac/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
apiregv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1"
proxyv1 "kubevirt.io/vm-console-proxy/api/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/yaml"

"kubevirt.io/ssp-operator/internal/common"
"kubevirt.io/ssp-operator/internal/env"
Expand Down Expand Up @@ -313,6 +317,15 @@ func reconcileRoleBinding(roleBinding *rbac.RoleBinding) common.ReconcileFunc {
func reconcileConfigMap(configMap core.ConfigMap) common.ReconcileFunc {
return func(request *common.Request) (common.ReconcileResult, error) {
configMap.Namespace = request.Instance.Namespace

tlsConfigYaml, err := createTlsConfigFile(request.Instance.Spec.TLSSecurityProfile)
if err != nil {
return common.ReconcileResult{}, err
}

const tlsConfigFilename = "tls-profile-v1.yaml"
configMap.Data[tlsConfigFilename] = tlsConfigYaml

return common.CreateOrUpdate(request).
NamespacedResource(&configMap).
WithAppLabels(operandName, operandComponent).
Expand Down Expand Up @@ -365,6 +378,51 @@ func getVmConsoleProxyImage() string {
return env.EnvOrDefault(env.VmConsoleProxyImageKey, defaultVmConsoleProxyImage)
}

func createTlsConfigFile(tlsProfile *ocpv1.TLSSecurityProfile) (string, error) {
if tlsProfile == nil {
// Returning empty config yaml. Default configuration will be used.
return "{}", nil
}

var profileSpec *ocpv1.TLSProfileSpec
if tlsProfile.Type == ocpv1.TLSProfileCustomType {
if tlsProfile.Custom == nil {
return "", fmt.Errorf("tlsProfile is invalid: custom filed is empty")
}
profileSpec = tlsProfile.Custom.TLSProfileSpec.DeepCopy()
} else {
predefinedProfile, found := ocpv1.TLSProfiles[tlsProfile.Type]
if !found {
return "", fmt.Errorf("tlsProfile type is invalid: %s", tlsProfile.Type)
}
profileSpec = predefinedProfile.DeepCopy()
}

result := proxyv1.TlsProfile{}

switch profileSpec.MinTLSVersion {
case ocpv1.VersionTLS10:
result.MinTLSVersion = proxyv1.VersionTLS10
case ocpv1.VersionTLS11:
result.MinTLSVersion = proxyv1.VersionTLS11
case ocpv1.VersionTLS12:
result.MinTLSVersion = proxyv1.VersionTLS12
case ocpv1.VersionTLS13:
result.MinTLSVersion = proxyv1.VersionTLS13
default:
return "", fmt.Errorf("unsupported TLS version: %s", profileSpec.MinTLSVersion)
}

result.Ciphers = crypto.OpenSSLToIANACipherSuites(profileSpec.Ciphers)

yamlBytes, err := yaml.Marshal(result)
if err != nil {
return "", fmt.Errorf("failed to marshal TLS profile cofing to yaml: %w", err)
}

return string(yamlBytes), nil
}

func findResourcesUsingLabels[PtrL interface {
*L
client.ObjectList
Expand Down
27 changes: 27 additions & 0 deletions internal/operands/vm-console-proxy/reconcile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
. "github.com/onsi/gomega"
"k8s.io/apimachinery/pkg/api/errors"

ocpv1 "github.com/openshift/api/config/v1"
routev1 "github.com/openshift/api/route/v1"
libhandler "github.com/operator-framework/operator-lib/handler"
apps "k8s.io/api/apps/v1"
Expand All @@ -22,10 +23,12 @@ import (
apiregv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1"
"k8s.io/utils/ptr"
kubevirt "kubevirt.io/api/core"
proxyv1 "kubevirt.io/vm-console-proxy/api/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
logf "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
"sigs.k8s.io/yaml"

ssp "kubevirt.io/ssp-operator/api/v1beta2"
"kubevirt.io/ssp-operator/internal/common"
Expand Down Expand Up @@ -140,6 +143,30 @@ var _ = Describe("VM Console Proxy Operand", func() {
To(MatchError(errors.IsNotFound, "errors.IsNotFound"))
})

It("should write TLS configuration to ConfigMap", func() {
request.Instance.Spec.TLSSecurityProfile = &ocpv1.TLSSecurityProfile{
Type: ocpv1.TLSProfileIntermediateType,
Intermediate: &ocpv1.IntermediateTLSProfile{},
}

_, err := operand.Reconcile(&request)
Expect(err).ToNot(HaveOccurred())

configMapKey := client.ObjectKeyFromObject(bundle.ConfigMap)

configMap := &core.ConfigMap{}
Expect(request.Client.Get(request.Context, configMapKey, configMap)).To(Succeed())

const tlsConfigFilename = "tls-profile-v1.yaml"
tlsConfig, exists := configMap.Data[tlsConfigFilename]
Expect(exists).To(BeTrue(), "ConfigMap should have TLS configuration file: "+tlsConfigFilename)

proxyProfile := &proxyv1.TlsProfile{}
Expect(yaml.Unmarshal([]byte(tlsConfig), proxyProfile)).To(Succeed())

Expect(proxyProfile.MinTLSVersion).To(Equal(proxyv1.VersionTLS12))
})

It("should remove cluster resources on cleanup", func() {
_, err := operand.Reconcile(&request)
Expect(err).ToNot(HaveOccurred())
Expand Down
202 changes: 202 additions & 0 deletions vendor/kubevirt.io/vm-console-proxy/api/LICENSE

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions vendor/kubevirt.io/vm-console-proxy/api/v1/constants.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 31 additions & 0 deletions vendor/kubevirt.io/vm-console-proxy/api/v1/types.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 64a8480

Please sign in to comment.