-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
Add collector for csr #650
Add collector for csr #650
Conversation
internal/collector/csr.go
Outdated
|
||
// addCSRConditionMetrics generates one metric for each possible csr condition status | ||
func addCSRConditionMetrics(cs certv1beta1.CertificateSigningRequestStatus) []*metric.Metric { | ||
approved := false |
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 CSR can either be approved or denied, right? If so, I would encode this here by only having either a approved
or denied
boolean, and derive the opposite via the !
operator.
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.
yes, this should be treated as an enum metric
internal/collector/csr.go
Outdated
approved := false | ||
denied := false | ||
if len(cs.Conditions) > 0 { | ||
for _, s := range cs.Conditions { |
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.
Just to make sure, if a CSR has multiple conditions, do all of the apply or only the most recent one?
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.
If it has multiple condition, then do all the apply, it can has "approve" and "denied" condition at the same time now.
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.
👍
0997048
to
c917158
Compare
internal/collector/csr.go
Outdated
} | ||
//"approved" if a certificate request has the | ||
// "Approved" condition and no "Denied" conditions; false otherwise. | ||
approved = approved && !denied |
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.
interpretation of data should be done at query time, not in kube-state-metrics, we should just expose each state with a 0 or 1 depending on whether it is in that state
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 little confused, what do you mean by "query time" ? do you mean I can just remove this line? when the csr have "approved" and "denied" condition at the same time, should I expose the metrics both 1 like this:
kube_csr_condition{csr="certificate-test",csr_condition="denied"} 1
kube_csr_condition{csr="certificate-test",csr_condition="approved"} 1
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.
@brancz if we don't interpret the data, there is the possibility for both approved and denied being true.
This upstream section seems to be the source of truth: https://github.com/kubernetes/kubernetes/blob/master/pkg/controller/certificates/certificate_controller_utils.go#L23
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.
Correct, but here we want to expose the raw data. Essentially the approved && !denied
is something that is up to a user to do in PromQL.
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 make sense, and it's how I did originally
internal/collector/csr.go
Outdated
func addCSRConditionMetrics(cs certv1beta1.CertificateSigningRequestStatus) []*metric.Metric { | ||
approved := false | ||
denied := false | ||
if len(cs.Conditions) > 0 { |
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.
No need for this, if it is 0, the for
loop will loop 0 times.
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 catch
internal/collector/csr.go
Outdated
approved := false | ||
denied := false | ||
if len(cs.Conditions) > 0 { | ||
for _, s := range cs.Conditions { |
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.
How about using GetCertApprovalCondition
here instead?
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'd like a duplication here, or it will bring go dependency here, WDYT?
internal/collector/csr.go
Outdated
approved := false | ||
denied := false | ||
if len(cs.Conditions) > 0 { | ||
for _, s := range cs.Conditions { |
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.
👍
de2dcea
to
d6ed2ee
Compare
In regards to the outdated discussion here: #650 (comment) If we want to expose the raw data, how about also exposing the count of denied and approved conditions instead of just @brancz @wanghaoran1988 what do you think? |
Just |
internal/collector/csr.go
Outdated
return []*metric.Metric{ | ||
&metric.Metric{ | ||
LabelValues: []string{"issued"}, | ||
Value: boolFloat64(len(cs.Certificate) > 0), |
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 is a state assessed based on data, not raw data, this should be done in PromQL
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.
@brancz So how about expose a metrics kube_csr_cert_length ?
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.
that works 👍
internal/collector/csr.go
Outdated
}, | ||
&metric.Metric{ | ||
LabelValues: []string{"pending"}, | ||
Value: boolFloat64(!(approved || denied)), |
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 as abbove
Yes, we can do the "count" in PromQL |
I am not quite sure we are on the same page @brancz. For the following CertificateSigningRequestStatus CertificateSigningRequestStatus {
[]Condition {
{ approved }, { approved }, { denied }, { denied }, { denied },
}
} I am suggesting to expose the number of approvals and denies like:
Instead of what we currently do:
What do you think? |
@mxinden This will not happen, we can only have one for each like: { approved }, { denied } |
The comment here states that there can be multiple denied conditions: // IsCertificateRequestApproved returns true if a certificate request has the
// "Approved" condition and no "Denied" conditions; false otherwise. Is there a specification somewhere? |
@mxinden Did some test with running "kubectl certificate approve/deny" many time against on one csr, finally, it only have one "approve" and one "denied" condition. |
6989976
to
782083e
Compare
782083e
to
5965270
Compare
Documentation/README.md
Outdated
@@ -62,7 +62,7 @@ Per group of metrics there is one file for each metrics. See each file for speci | |||
* [Secret Metrics](secret-metrics.md) | |||
* [ConfigMap Metrics](configmap-metrics.md) | |||
* [Ingress Metrics](ingress-metrics.md) | |||
|
|||
* [CSR Metrics](csr-metrics.md) |
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.
* [CSR Metrics](csr-metrics.md) | |
* [CertificateSigningRequest Metrics](certificatesigningrequest-metrics.md) |
Suggesting this, as the convention seems to be the resource type name rather than resource abbreviation
internal/collector/csr.go
Outdated
@@ -0,0 +1,152 @@ | |||
/* |
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 should be renamed to certificatesigningrequest.go
IMO
internal/collector/csr.go
Outdated
) | ||
|
||
var ( | ||
descCSRLabelsName = "kube_csr_labels" |
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.
descCSRLabelsName = "kube_csr_labels" | |
descCSRLabelsName = "kube_certificatesigningrequest_labels" |
Documentation/csr-metrics.md
Outdated
|
||
| Metric name| Metric type | Labels/tags | Status | | ||
| ---------- | ----------- | ----------- | ----------- | | ||
| kube_csr_created| Gauge | `csr`=<csr-name>| STABLE | |
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.
| kube_csr_created| Gauge | `csr`=<csr-name>| STABLE | | |
| kube_certificatesigningrequest_created| Gauge | `csr`=<csr-name>| STABLE | |
I understand that this may be concerning given the length, but I see instances like kube_persistentvolumeclaim_resource_requests_storage_bytes
internal/collector/builder.go
Outdated
@@ -134,6 +135,7 @@ var availableCollectors = map[string]func(f *Builder) *coll.Collector{ | |||
"secrets": func(b *Builder) *coll.Collector { return b.buildSecretCollector() }, | |||
"services": func(b *Builder) *coll.Collector { return b.buildServiceCollector() }, | |||
"statefulsets": func(b *Builder) *coll.Collector { return b.buildStatefulSetCollector() }, | |||
"csr": func(b *Builder) *coll.Collector { return b.buildCsrCollector() }, |
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.
"csr": func(b *Builder) *coll.Collector { return b.buildCsrCollector() }, | |
"certificatesigningrequests": func(b *Builder) *coll.Collector { return b.buildCsrCollector() }, |
@wanghaoran1988 make sure you run either |
Sorry, I just back from paternity leave, will have an update this week. |
ff995cf
to
4e5a9b1
Compare
@mxinden @tariq1890 Could you take a look ? I rebased and renamed. |
@@ -0,0 +1,8 @@ | |||
# CSR Metrics |
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.
# CSR Metrics | |
# CertificateSigningRequest Metrics |
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.
@wanghaoran1988 Let's change this as well.
|
||
| Metric name| Metric type | Labels/tags | Status | | ||
| ---------- | ----------- | ----------- | ----------- | | ||
| kube_certificatesigningrequest_created| Gauge | `csr`=<csr-name>| STABLE | |
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.
s/csr/certificatesigningrequest
var ( | ||
descCSRLabelsName = "kube_certificatesigningrequest_labels" | ||
descCSRLabelsHelp = "Kubernetes labels converted to Prometheus labels." | ||
descCSRLabelsDefaultLabels = []string{"csr"} |
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.
descCSRLabelsDefaultLabels = []string{"csr"} | |
descCSRLabelsDefaultLabels = []string{"certificatesigningrequest"} |
4e5a9b1
to
df7727f
Compare
comments addressed, @tariq1890 PTAL |
internal/collector/builder.go
Outdated
"secrets": func(b *Builder) *coll.Collector { return b.buildSecretCollector() }, | ||
"services": func(b *Builder) *coll.Collector { return b.buildServiceCollector() }, | ||
"statefulsets": func(b *Builder) *coll.Collector { return b.buildStatefulSetCollector() }, | ||
"certificatesigningrequests": func(b *Builder) *coll.Collector { return b.buildCsrCollector() }, |
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 list actually follows alphabetical order. Let's continue that :)
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.
Sorry to have missed this earlier.
for i, c := range cases { | ||
c.Func = metric.ComposeMetricGenFuncs(csrMetricFamilies) | ||
if err := c.run(); err != nil { | ||
t.Errorf("unexpected collecting result in %vth run:\n%s", i, err) |
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.
t.Errorf("unexpected collecting result in %vth run:\n%s", i, err) | |
t.Errorf("unexpected error when collecting result in %vth run:\n%s", i, err) |
@wanghaoran1988 Thanks for your patience! This should be my last round of review comments. LGTM pending those comments and @brancz 's final word of approval. |
df7727f
to
cac0765
Compare
@tariq1890 comments addressed |
@@ -0,0 +1,8 @@ | |||
# CertificatesSigningRequest Metrics |
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.
# CertificatesSigningRequest Metrics | |
# CertificateSigningRequest Metrics |
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.
there is an extra s
.
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.
done
pkg/options/collector.go
Outdated
"statefulsets": struct{}{}, | ||
"configmaps": struct{}{}, | ||
"cronjobs": struct{}{}, | ||
"certificatesigningrequests": struct{}{}, |
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.
can this go to the top?
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.
done
cac0765
to
6793b68
Compare
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
/assign @mxinden for final approval. Possible to fit this into release 1.6 once merged? |
lgtm but leaving final decision up to @mxinden whether to include in 1.6 or not |
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.
Thanks for the work @wanghaoran1988!
Let's include this in kube state metrics 1.6. /lgtm /approve |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: mxinden, tariq1890, wanghaoran1988 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 |
Yes! Thanks once again @wanghaoran1988 :) |
What this PR does / why we need it:
Which issue(s) this PR fixes (optional, in
fixes #<issue number>(, fixes #<issue_number>, ...)
format, will close the issue(s) when PR gets merged):Fixes #649