-
Notifications
You must be signed in to change notification settings - Fork 244
OCPBUGS-57049: cert inspection: add an option to humanize refresh period annotation #1981
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
OCPBUGS-57049: cert inspection: add an option to humanize refresh period annotation #1981
Conversation
@vrutkovs: This pull request references Jira Issue OCPBUGS-57049, which is valid. 3 validation(s) were run on this bug
Requesting review from QA contact: The bug has been updated to refer to the pull request using the external bug tracker. In response to this:
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. |
There was a problem hiding this 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{ |
There was a problem hiding this comment.
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 ?
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
?
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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
?
There was a problem hiding this comment.
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)
ede4571
to
1920898
Compare
pkg/certs/cert-inspection/certgraphanalysis/metadata_options.go
Outdated
Show resolved
Hide resolved
pkg/certs/cert-inspection/certgraphanalysis/metadata_options.go
Outdated
Show resolved
Hide resolved
u := uint64(d) | ||
if d < 0 { | ||
u = -u | ||
} | ||
|
||
if u == 0 { | ||
return "0s" | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 | |
} |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
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) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 | |
) |
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" | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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") |
{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"}, |
There was a problem hiding this comment.
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:
{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"}, |
There was a problem hiding this 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
pkg/certs/cert-inspection/certgraphanalysis/metadata_options.go
Outdated
Show resolved
Hide resolved
pkg/certs/cert-inspection/certgraphanalysis/metadata_options.go
Outdated
Show resolved
Hide resolved
pkg/certs/cert-inspection/certgraphanalysis/metadata_options.go
Outdated
Show resolved
Hide resolved
1aad7e3
to
2bd99a9
Compare
const ( | ||
rewritePrefix = "rewritten.cert-info.openshift.io/" | ||
// Unit values in seconds | ||
year = 60 * 60 * 24 * 365 |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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{} |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
2bd99a9
to
f7d031e
Compare
…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
f7d031e
to
507f6ad
Compare
@wangke19 it looks like we are about to merge this PR. Is there anything else we should take into consideration ? |
lgtm |
@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. |
/lgtm |
[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 |
@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 Issue OCPBUGS-57049 has not been moved to the MODIFIED state. In response to this:
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. |
This option converts
time.Parse Duration
-compatible string of duration (i.e.77h30m00s
) intohuman-readable string (
3d5h30m
) so that TLS registry markdowns have improved readability