Skip to content

Commit 1c0f27c

Browse files
ngopalak-redhatk8s-ci-robot
authored andcommitted
2940: optionally enable TLS 1.3 for SPO webhook
1 parent a369f83 commit 1c0f27c

File tree

3 files changed

+175
-4
lines changed

3 files changed

+175
-4
lines changed

cmd/security-profiles-operator/main.go

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,11 +101,17 @@ const (
101101
auditLogMaxAgeParam string = "audit-log-maxage"
102102
enricherFiltersJsonParam string = "enricher-filters-json"
103103
enricherLogSourceParam string = "enricher-log-source"
104+
tlsMinVersionParam string = "tls-min-version"
105+
defaultTlsMinVersion string = "1.2"
104106
)
105107

106108
var (
107-
sync = time.Second * 30
108-
setupLog = ctrl.Log.WithName("setup")
109+
sync = time.Second * 30
110+
setupLog = ctrl.Log.WithName("setup")
111+
tlsMinVersionMap = map[string]uint16{
112+
"1.2": tls.VersionTLS12,
113+
"1.3": tls.VersionTLS13,
114+
}
109115
)
110116

111117
func main() {
@@ -226,6 +232,11 @@ func main() {
226232
Value: false,
227233
Usage: "the webhook k8s resources are statically managed (default false)",
228234
},
235+
&cli.GenericFlag{
236+
Name: tlsMinVersionParam,
237+
Value: util.NewEnumValue([]string{"1.2", "1.3"}, "1.2"),
238+
Usage: "minimum TLS version to use for the SPO webhooks. Supported values: 1.2, 1.3. (default: 1.2)",
239+
},
229240
},
230241
},
231242
&cli.Command{
@@ -797,12 +808,23 @@ func runWebhook(ctx *cli.Context, info *version.Info) error {
797808

798809
port := ctx.Int("port")
799810

800-
disableHTTP2 := func(c *tls.Config) {
811+
var tlsMinVersionStr string
812+
813+
tlsMinVersion, ok := ctx.Generic(tlsMinVersionParam).(util.EnumValue)
814+
if !ok {
815+
tlsMinVersionStr = defaultTlsMinVersion
816+
} else {
817+
tlsMinVersionStr = tlsMinVersion.String()
818+
}
819+
820+
tlsConfig := func(c *tls.Config) {
801821
c.NextProtos = []string{"http/1.1"}
822+
c.MinVersion = tlsMinVersionMap[tlsMinVersionStr]
802823
}
824+
803825
webhookServerOptions := webhook.Options{
804826
Port: port,
805-
TLSOpts: []func(config *tls.Config){disableHTTP2},
827+
TLSOpts: []func(config *tls.Config){tlsConfig},
806828
}
807829

808830
webhookServer := webhook.NewServer(webhookServerOptions)

internal/pkg/util/enum.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
Copyright 2025 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package util
18+
19+
import (
20+
"flag"
21+
"fmt"
22+
"strings"
23+
)
24+
25+
type EnumValue struct {
26+
Enum []string
27+
Default string
28+
selected string
29+
}
30+
31+
var _ flag.Value = (*EnumValue)(nil)
32+
33+
// NewEnumValue returns a new EnumValue. Returns nil if defaultValue is not found in enum.
34+
func NewEnumValue(enum []string, defaultValue string) *EnumValue {
35+
for _, v := range enum {
36+
if v == defaultValue {
37+
return &EnumValue{Enum: enum, Default: defaultValue}
38+
}
39+
}
40+
41+
return nil
42+
}
43+
44+
// Set method is used by cli.GenericFlag. But the IDE won't recognize it.
45+
func (e *EnumValue) Set(value string) error {
46+
for _, enum := range e.Enum {
47+
if strings.EqualFold(enum, value) {
48+
e.selected = enum
49+
50+
return nil
51+
}
52+
}
53+
54+
return fmt.Errorf("allowed values are %s", strings.Join(e.Enum, ", "))
55+
}
56+
57+
func (e *EnumValue) String() string {
58+
if e.selected == "" {
59+
return e.Default
60+
}
61+
62+
return e.selected
63+
}

internal/pkg/util/enum_test.go

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/*
2+
Copyright 2025 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package util
18+
19+
import (
20+
"flag"
21+
"testing"
22+
)
23+
24+
func TestEnumValue(t *testing.T) {
25+
t.Parallel()
26+
27+
// Test NewEnumValue
28+
enum := NewEnumValue([]string{"1.2", "1.3"}, "1.2")
29+
if enum == nil {
30+
t.Fatal("NewEnumValue should not return nil for valid input")
31+
}
32+
33+
if enum.Default != "1.2" {
34+
t.Errorf("expected default '1.2', got '%s'", enum.Default)
35+
}
36+
37+
// Test invalid constructor
38+
if NewEnumValue([]string{"1.2", "1.3"}, "1.1") != nil {
39+
t.Error("NewEnumValue should return nil when default not in enum")
40+
}
41+
42+
if NewEnumValue([]string{}, "test") != nil {
43+
t.Error("NewEnumValue should return nil for empty enum")
44+
}
45+
46+
// Test String method returns default initially
47+
if enum.String() != "1.2" {
48+
t.Errorf("expected default '1.2', got '%s'", enum.String())
49+
}
50+
51+
// Test Set method with valid inputs
52+
if err := enum.Set("1.3"); err != nil {
53+
t.Errorf("Set failed for valid value: %v", err)
54+
}
55+
56+
if enum.String() != "1.3" {
57+
t.Errorf("expected '1.3' after Set, got '%s'", enum.String())
58+
}
59+
60+
// Test Set method with invalid inputs
61+
if err := enum.Set("1.1"); err == nil {
62+
t.Error("Set should fail for invalid value")
63+
}
64+
65+
// Test case-insensitive matching
66+
enumCase := NewEnumValue([]string{"Debug", "Info"}, "Info")
67+
if err := enumCase.Set("debug"); err != nil {
68+
t.Errorf("Set should work case-insensitively: %v", err)
69+
}
70+
71+
if enumCase.String() != "Debug" {
72+
t.Errorf("expected canonical case 'Debug', got '%s'", enumCase.String())
73+
}
74+
75+
// Test flag.Value interface
76+
var _ flag.Value = enum
77+
78+
// Test error message format
79+
err := enum.Set("invalid")
80+
81+
expectedMsg := "allowed values are 1.2, 1.3"
82+
83+
if err.Error() != expectedMsg {
84+
t.Errorf("expected error '%s', got '%s'", expectedMsg, err.Error())
85+
}
86+
}

0 commit comments

Comments
 (0)