Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions internal/controller/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"log"
"maps"
"net"
"regexp"
"slices"
"strconv"
"strings"
Expand Down Expand Up @@ -576,13 +577,25 @@ func getPeerCertName(etcdClusterName string) string {
return peerCertName
}

// validityDurationDayPrefix matches a leading integer day segment, e.g. "365d" or the "100d" in "100d12h".
var validityDurationDayPrefix = regexp.MustCompile(`^(\d+)d`)

// parseValidityDuration parses a duration string and returns the parsed duration.
// If the customizedDuration is empty, it returns the defaultDuration.
// A leading day segment (e.g. "365d", "100d12h") is expanded to hours, since
// time.ParseDuration does not support the "d" unit.
// Returns an error if the duration string cannot be parsed.
func parseValidityDuration(customizedDuration string, defaultDuration time.Duration) (time.Duration, error) {
if customizedDuration == "" {
return defaultDuration, nil
}
if m := validityDurationDayPrefix.FindStringSubmatch(customizedDuration); m != nil {
days, err := strconv.Atoi(m[1])
if err != nil {
return 0, fmt.Errorf("failed to parse ValidityDuration: %w", err)
}
customizedDuration = fmt.Sprintf("%dh%s", days*24, customizedDuration[len(m[0]):])
}
duration, err := time.ParseDuration(customizedDuration)
if err != nil {
return 0, fmt.Errorf("failed to parse ValidityDuration: %w", err)
Expand Down
30 changes: 30 additions & 0 deletions internal/controller/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1090,3 +1090,33 @@ func TestCreateCMCertificateConfig(t *testing.T) {
})
}
}

func TestParseValidityDuration(t *testing.T) {
tests := []struct {
name string
input string
expected time.Duration
expectedErr bool
}{
{name: "day suffix", input: "365d", expected: 365 * 24 * time.Hour},
{name: "days and hours", input: "100d12h", expected: 100*24*time.Hour + 12*time.Hour},
{name: "plain go duration", input: "24h", expected: 24 * time.Hour},
{name: "minutes", input: "90m", expected: 90 * time.Minute},
{name: "empty returns default", input: "", expected: certInterface.DefaultCertManagerValidity},
{name: "invalid string", input: "abc", expectedErr: true},
{name: "day unit without value", input: "d", expectedErr: true},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
duration, err := parseValidityDuration(tt.input, certInterface.DefaultCertManagerValidity)
if tt.expectedErr {
require.Error(t, err)
assert.ErrorContains(t, err, "failed to parse ValidityDuration")
return
}
require.NoError(t, err)
assert.Equal(t, tt.expected, duration)
})
}
}