Skip to content

Conversation

vrutkovs
Copy link
Member

This option converts time.Parse Duration-compatible string of duration (i.e. 77h30m00s) into
human-readable string (3d5h30m) so that TLS registry markdowns have improved readability

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Jul 24, 2025
@openshift-ci-robot
Copy link

@vrutkovs: This pull request references Jira Issue OCPBUGS-57049, which is valid.

3 validation(s) were run on this bug
  • bug is open, matching expected state (open)
  • bug target version (4.20.0) matches configured target version for branch (4.20.0)
  • bug is in the state POST, which is one of the valid states (NEW, ASSIGNED, POST)

Requesting review from QA contact:
/cc @wangke19

The bug has been updated to refer to the pull request using the external bug tracker.

In response to this:

This option converts time.Parse Duration-compatible string of duration (i.e. 77h30m00s) into
human-readable string (3d5h30m) so that TLS registry markdowns have improved readability

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci-robot openshift-ci-robot added the jira/valid-bug Indicates that a referenced Jira bug is valid for the branch this PR is targeting. label Jul 24, 2025
Copy link
Contributor

@p0lyn0mial p0lyn0mial left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

return timestampReg.ReplaceAllString(path, "<timestamp>.pem")
},
}
HumanizeRewritePeriod = &metadataOptions{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, and how is this var being used ? by external tools that pull this library ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

origin would run this function to update secrets/configmap annotation when raw TLS data is collected

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: how about changing the name to RewriteRefreshPeriod or ReformatRefreshPeriod or TransformRefreshPeriod ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, lets go with Rewrite - its more similar to what other functions are named

return
}
if period, ok := secret.Annotations[certrotation.CertificateRefreshPeriodAnnotation]; ok {
if d, err := time.ParseDuration(period); err == nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: i would change to: (reads a bit easier)

d, err := time.ParseDuration(period)
if err != nil {
  fmt.Fprintf(os.Stderr, "Failed to parse rewrite period %s: %v\n", period, err)
  return
}
humanReadableDate := durationToHumanReadableString(d)
secret.Annotations[certrotation.CertificateRefreshPeriodAnnotation] = humanReadableDate
secret.Annotations[rewritePrefix+"HumanizeRewritePeriod"] = period

return
}
if period, ok := configMap.Annotations[certrotation.CertificateRefreshPeriodAnnotation]; ok {
if d, err := time.ParseDuration(period); err == nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

if d, err := time.ParseDuration(period); err == nil {
humanReadableDate := durationToHumanReadableString(d)
secret.Annotations[certrotation.CertificateRefreshPeriodAnnotation] = humanReadableDate
secret.Annotations[rewritePrefix+"HumanizeRewritePeriod"] = period
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't this be rewritePrefix+certrotation.CertificateRefreshPeriodAnnotation ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This annotation stores original value we may need for debugging. It should include the name of the function which did the rewrite (it's expected that the function would rewrite just one annotation, so it's more beneficial to save the function name instead of the annotation name, so that the source of the error could be found easier)

Comment on lines 276 to 274
u := uint64(d)
if d < 0 {
u = -u
}

if u == 0 {
return "0s"
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
u := uint64(d)
if d < 0 {
u = -u
}
if u == 0 {
return "0s"
}
if d == 0 {
return "0s"
}
// Handle negative durations by taking absolute value
u := d
if d < 0 {
u = -d
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the idea of checking for d == 0 first, but we also still want to do u := uint64(d) first to make sure its converted from the start

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, we don't need to store values as uint64 - it's best to be rounded to seconds

Comment on lines 286 to 291
year := uint64(time.Hour) * 24 * 365
month := uint64(time.Hour) * 24 * 30
day := uint64(time.Hour) * 24
hour := uint64(time.Hour)
minute := uint64(time.Minute)
second := uint64(time.Second)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
year := uint64(time.Hour) * 24 * 365
month := uint64(time.Hour) * 24 * 30
day := uint64(time.Hour) * 24
hour := uint64(time.Hour)
minute := uint64(time.Minute)
second := uint64(time.Second)
totalSeconds := uint64(u.Seconds())
// Define time units in seconds
const (
year = 365 * 24 * 3600
month = 30 * 24 * 3600
day = 24 * 3600
hour = 3600
minute = 60
second = 1
)

Comment on lines 295 to 336
years := u / year
u %= year
if years > 0 {
b.WriteString(strconv.FormatUint(years, 10))
b.WriteString("y")
}

months := u / month
u %= month
if months > 0 {
b.WriteString(strconv.FormatUint(months, 10))
b.WriteString("mo")
}

days := u / day
u %= day
if days > 0 {
b.WriteString(strconv.FormatUint(days, 10))
b.WriteString("d")
}

hours := u / hour
u %= hour
if hours > 0 {
b.WriteString(strconv.FormatUint(hours, 10))
b.WriteString("h")
}

minutes := u / minute
u %= minute
if minutes > 0 {
b.WriteString(strconv.FormatUint(minutes, 10))
b.WriteString("m")
}

seconds := u / second
u %= second
if seconds > 0 {
b.WriteString(strconv.FormatUint(seconds, 10))
b.WriteString("s")
}

if b.Len() == 0 {
return "0s"
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
years := u / year
u %= year
if years > 0 {
b.WriteString(strconv.FormatUint(years, 10))
b.WriteString("y")
}
months := u / month
u %= month
if months > 0 {
b.WriteString(strconv.FormatUint(months, 10))
b.WriteString("mo")
}
days := u / day
u %= day
if days > 0 {
b.WriteString(strconv.FormatUint(days, 10))
b.WriteString("d")
}
hours := u / hour
u %= hour
if hours > 0 {
b.WriteString(strconv.FormatUint(hours, 10))
b.WriteString("h")
}
minutes := u / minute
u %= minute
if minutes > 0 {
b.WriteString(strconv.FormatUint(minutes, 10))
b.WriteString("m")
}
seconds := u / second
u %= second
if seconds > 0 {
b.WriteString(strconv.FormatUint(seconds, 10))
b.WriteString("s")
}
if b.Len() == 0 {
return "0s"
}
years := u / year
writeUnit := func(value uint64, suffix string) {
if value > 0 {
b.WriteString(strconv.FormatUint(value, 10))
b.WriteString(suffix)
}
}
years := totalSeconds / year
totalSeconds %= year
writeUnit(years, "y")
months := totalSeconds / month
totalSeconds %= month
writeUnit(months, "mo")
days := totalSeconds / day
totalSeconds %= day
writeUnit(days, "d")
hours := totalSeconds / hour
totalSeconds %= hour
writeUnit(hours, "h")
minutes := totalSeconds / minute
totalSeconds %= minute
writeUnit(minutes, "m")
seconds := totalSeconds
writeUnit(seconds, "s")

Comment on lines 13 to 20
{time.Hour * 24 * 365 * 9, "9y"},
{time.Hour * 24 * 365, "1y"},
{time.Hour * 24 * 30 * 5, "5mo"},
{time.Hour * 24 * 30, "1mo"},
{time.Hour * 24 * 2, "2d"},
{time.Hour * 2, "2h"},
{time.Hour*24*3 + time.Hour*2, "3d2h"},
{time.Hour*24*5 + time.Hour*4 + time.Minute*25, "5d4h25m"},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

covers various cases including zero, positive, negative, and composite durations:

Suggested change
{time.Hour * 24 * 365 * 9, "9y"},
{time.Hour * 24 * 365, "1y"},
{time.Hour * 24 * 30 * 5, "5mo"},
{time.Hour * 24 * 30, "1mo"},
{time.Hour * 24 * 2, "2d"},
{time.Hour * 2, "2h"},
{time.Hour*24*3 + time.Hour*2, "3d2h"},
{time.Hour*24*5 + time.Hour*4 + time.Minute*25, "5d4h25m"},
{0, "0s"},
{time.Second, "1s"},
{2 * time.Second, "2s"},
{time.Minute, "1m"},
{time.Minute + 30*time.Second, "1m30s"},
{time.Hour, "1h"},
{25 * time.Hour, "1d1h"},
{30 * 24 * time.Hour, "1mo"},
{365 * 24 * time.Hour, "1y"},
{400 * 24 * time.Hour, "1y1mo5d"},
{-time.Minute, "1m"}, // negative duration
{-400 * 24 * time.Hour, "1y1mo5d"}, // negative composite
{3*time.Minute + 4*time.Second, "3m4s"},

Copy link
Contributor

@p0lyn0mial p0lyn0mial left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a few more comments/questions

@vrutkovs vrutkovs force-pushed the cert-refresh-period-rewrite branch 4 times, most recently from 1aad7e3 to 2bd99a9 Compare July 25, 2025 09:48
const (
rewritePrefix = "rewritten.cert-info.openshift.io/"
// Unit values in seconds
year = 60 * 60 * 24 * 365
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please move this vars inside durationToHumanReadableString so that they are private to that method.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't we reinitialize them every time we call a function?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point, we would, but these var will only be used by that function and it would be nice to keep them inside that function for clarity. i don't think this code must be lightning fast. an alternative would be to create an internal pkg for that function.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, okay, sure


func humanizeRefreshPeriodFromMetadata(annotations map[string]string) {
if annotations == nil {
annotations = map[string]string{}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's return here, in go a nil map is equivalent to an empty map from which reading is possible.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, in that case we don't need this check at all - annotations[certrotation.CertificateRefreshPeriodAnnotation] will guard us. Added a unit test

@vrutkovs vrutkovs force-pushed the cert-refresh-period-rewrite branch from 2bd99a9 to f7d031e Compare July 25, 2025 10:05
…n-readable

This option converts `time.ParseDuration`-compatible string of duration (i.e. `77h30m00s`) into
human-redable string (`3d5h30m`) so that TLS registry markdowns have improved readability
@vrutkovs vrutkovs force-pushed the cert-refresh-period-rewrite branch from f7d031e to 507f6ad Compare July 25, 2025 10:12
@p0lyn0mial
Copy link
Contributor

@wangke19 it looks like we are about to merge this PR. Is there anything else we should take into consideration ?

@wangke19
Copy link
Contributor

wangke19 commented Jul 25, 2025

@wangke19 it looks like we are about to merge this PR. Is there anything else we should take into consideration ?

lgtm

Copy link
Contributor

openshift-ci bot commented Jul 25, 2025

@vrutkovs: all tests passed!

Full PR test history. Your PR dashboard.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@p0lyn0mial
Copy link
Contributor

/lgtm
/approve

@openshift-ci openshift-ci bot added the lgtm Indicates that a PR is ready to be merged. label Jul 25, 2025
Copy link
Contributor

openshift-ci bot commented Jul 25, 2025

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: p0lyn0mial, vrutkovs

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jul 25, 2025
@openshift-merge-bot openshift-merge-bot bot merged commit 7f9bc3e into openshift:master Jul 25, 2025
4 checks passed
@openshift-ci-robot
Copy link

@vrutkovs: Jira Issue OCPBUGS-57049: Some pull requests linked via external trackers have merged:

The following pull requests linked via external trackers have not merged:

These pull request must merge or be unlinked from the Jira bug in order for it to move to the next state. Once unlinked, request a bug refresh with /jira refresh.

Jira Issue OCPBUGS-57049 has not been moved to the MODIFIED state.

In response to this:

This option converts time.Parse Duration-compatible string of duration (i.e. 77h30m00s) into
human-readable string (3d5h30m) so that TLS registry markdowns have improved readability

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. jira/valid-bug Indicates that a referenced Jira bug is valid for the branch this PR is targeting. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. lgtm Indicates that a PR is ready to be merged.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants