Skip to content
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

Merged
merged 1 commit into from
Mar 24, 2019

Conversation

wanghaoran1988
Copy link
Contributor

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

@k8s-ci-robot k8s-ci-robot added the cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. label Jan 31, 2019
@k8s-ci-robot k8s-ci-robot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Jan 31, 2019

// addCSRConditionMetrics generates one metric for each possible csr condition status
func addCSRConditionMetrics(cs certv1beta1.CertificateSigningRequestStatus) []*metric.Metric {
approved := false
Copy link
Contributor

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.

Copy link
Member

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

approved := false
denied := false
if len(cs.Conditions) > 0 {
for _, s := range cs.Conditions {
Copy link
Contributor

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?

Copy link
Contributor Author

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.

Copy link
Contributor

Choose a reason for hiding this comment

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

👍

@wanghaoran1988
Copy link
Contributor Author

}
//"approved" if a certificate request has the
// "Approved" condition and no "Denied" conditions; false otherwise.
approved = approved && !denied
Copy link
Member

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

Copy link
Contributor Author

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

Copy link
Contributor

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

Copy link
Member

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.

Copy link
Contributor Author

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

func addCSRConditionMetrics(cs certv1beta1.CertificateSigningRequestStatus) []*metric.Metric {
approved := false
denied := false
if len(cs.Conditions) > 0 {
Copy link
Contributor

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

good catch

approved := false
denied := false
if len(cs.Conditions) > 0 {
for _, s := range cs.Conditions {
Copy link
Contributor

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?

Copy link
Contributor Author

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?

approved := false
denied := false
if len(cs.Conditions) > 0 {
for _, s := range cs.Conditions {
Copy link
Contributor

Choose a reason for hiding this comment

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

👍

@wanghaoran1988 wanghaoran1988 force-pushed the add_crs_collector branch 2 times, most recently from de2dcea to d6ed2ee Compare February 6, 2019 14:24
@mxinden
Copy link
Contributor

mxinden commented Feb 6, 2019

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 true or false?

@brancz @wanghaoran1988 what do you think?

@brancz
Copy link
Member

brancz commented Feb 6, 2019

Just true and false. Count is then something a user can do in PromQL 🙂 .

return []*metric.Metric{
&metric.Metric{
LabelValues: []string{"issued"},
Value: boolFloat64(len(cs.Certificate) > 0),
Copy link
Member

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

Copy link
Contributor Author

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 ?

Copy link
Member

Choose a reason for hiding this comment

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

that works 👍

},
&metric.Metric{
LabelValues: []string{"pending"},
Value: boolFloat64(!(approved || denied)),
Copy link
Member

Choose a reason for hiding this comment

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

Same as abbove

@wanghaoran1988
Copy link
Contributor Author

Yes, we can do the "count" in PromQL

@mxinden
Copy link
Contributor

mxinden commented Feb 6, 2019

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:

kube_csr_condition{ condition="approved" } 2
kube_csr_condition{ conditiion="denied" } 3

Instead of what we currently do:

kube_csr_condition{ condition="approved" } 1
kube_csr_condition{ conditiion="denied" } 1

What do you think?

@wanghaoran1988
Copy link
Contributor Author

{ approved }, { approved }, { denied }, { denied }, { denied },

@mxinden This will not happen, we can only have one for each like: { approved }, { denied }

@mxinden
Copy link
Contributor

mxinden commented Feb 6, 2019

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.

https://github.com/kubernetes/kubernetes/blob/master/pkg/controller/certificates/certificate_controller_utils.go#L21-L22

Is there a specification somewhere?

@wanghaoran1988
Copy link
Contributor Author

@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.

@wanghaoran1988 wanghaoran1988 force-pushed the add_crs_collector branch 2 times, most recently from 6989976 to 782083e Compare February 12, 2019 08:40
@wanghaoran1988
Copy link
Contributor Author

@mxinden @brancz Could you take another look? I had a rebase again and addressed the comments.

@@ -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)
Copy link
Contributor

@tariq1890 tariq1890 Feb 15, 2019

Choose a reason for hiding this comment

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

Suggested change
* [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

@@ -0,0 +1,152 @@
/*
Copy link
Contributor

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

)

var (
descCSRLabelsName = "kube_csr_labels"
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
descCSRLabelsName = "kube_csr_labels"
descCSRLabelsName = "kube_certificatesigningrequest_labels"


| Metric name| Metric type | Labels/tags | Status |
| ---------- | ----------- | ----------- | ----------- |
| kube_csr_created| Gauge | `csr`=&lt;csr-name&gt;| STABLE |
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
| kube_csr_created| Gauge | `csr`=&lt;csr-name&gt;| STABLE |
| kube_certificatesigningrequest_created| Gauge | `csr`=&lt;csr-name&gt;| STABLE |

I understand that this may be concerning given the length, but I see instances like kube_persistentvolumeclaim_resource_requests_storage_bytes

@@ -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() },
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
"csr": func(b *Builder) *coll.Collector { return b.buildCsrCollector() },
"certificatesigningrequests": func(b *Builder) *coll.Collector { return b.buildCsrCollector() },

@tariq1890
Copy link
Contributor

@mxinden @brancz I've added my non-maintainer review comments (apologize if it's inappropriate) for ensuring nomenclature consistency.

@tariq1890
Copy link
Contributor

@wanghaoran1988 make sure you run either go mod tidy or go mod vendor. That would fix one of the travic CI fails :).

@wanghaoran1988
Copy link
Contributor Author

Sorry, I just back from paternity leave, will have an update this week.

@wanghaoran1988 wanghaoran1988 force-pushed the add_crs_collector branch 2 times, most recently from ff995cf to 4e5a9b1 Compare March 18, 2019 05:23
@wanghaoran1988
Copy link
Contributor Author

@mxinden @tariq1890 Could you take a look ? I rebased and renamed.

@@ -0,0 +1,8 @@
# CSR Metrics
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
# CSR Metrics
# CertificateSigningRequest Metrics

Copy link
Contributor

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`=&lt;csr-name&gt;| STABLE |
Copy link
Contributor

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"}
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
descCSRLabelsDefaultLabels = []string{"csr"}
descCSRLabelsDefaultLabels = []string{"certificatesigningrequest"}

@wanghaoran1988
Copy link
Contributor Author

comments addressed, @tariq1890 PTAL

"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() },
Copy link
Contributor

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 :)

Copy link
Contributor

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)
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
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)

@tariq1890
Copy link
Contributor

@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.

@wanghaoran1988
Copy link
Contributor Author

@tariq1890 comments addressed

@@ -0,0 +1,8 @@
# CertificatesSigningRequest Metrics
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
# CertificatesSigningRequest Metrics
# CertificateSigningRequest Metrics

Copy link
Contributor

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

"statefulsets": struct{}{},
"configmaps": struct{}{},
"cronjobs": struct{}{},
"certificatesigningrequests": struct{}{},
Copy link
Contributor

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

Copy link
Contributor

@tariq1890 tariq1890 left a comment

Choose a reason for hiding this comment

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

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Mar 21, 2019
@tariq1890
Copy link
Contributor

/assign @mxinden for final approval.

Possible to fit this into release 1.6 once merged?

@brancz
Copy link
Member

brancz commented Mar 21, 2019

lgtm but leaving final decision up to @mxinden whether to include in 1.6 or not

Copy link
Contributor

@mxinden mxinden left a 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!

@mxinden
Copy link
Contributor

mxinden commented Mar 24, 2019

Let's include this in kube state metrics 1.6.

/lgtm

/approve

@k8s-ci-robot
Copy link
Contributor

[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 /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Mar 24, 2019
@k8s-ci-robot k8s-ci-robot merged commit 907c526 into kubernetes:master Mar 24, 2019
@tariq1890
Copy link
Contributor

Yes! Thanks once again @wanghaoran1988 :)

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. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. lgtm "Looks good to me", indicates that a PR is ready to be merged. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add collector for CSR
5 participants