[PodSecurity] Fix up metrics & add tests

Update pod security metrics to match the spec in the KEP.
This commit is contained in:
Tim Allclair
2021-10-25 21:43:15 -07:00
parent ac2d872ed9
commit e46928c0b1
8 changed files with 313 additions and 88 deletions

View File

@@ -18,7 +18,9 @@ package auth
import (
"context"
"crypto/tls"
"fmt"
"io/ioutil"
"net"
"net/http"
"net/url"
@@ -37,6 +39,7 @@ import (
"k8s.io/client-go/rest"
"k8s.io/component-base/featuregate"
featuregatetesting "k8s.io/component-base/featuregate/testing"
"k8s.io/component-base/metrics/testutil"
kubeapiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing"
"k8s.io/kubernetes/pkg/capabilities"
"k8s.io/kubernetes/pkg/features"
@@ -67,6 +70,8 @@ func TestPodSecurity(t *testing.T) {
ExemptRuntimeClasses: []string{},
}
podsecuritytest.Run(t, opts)
ValidatePluginMetrics(t, opts.ClientConfig)
}
// TestPodSecurityGAOnly ensures policies pass with only GA features enabled
@@ -88,6 +93,8 @@ func TestPodSecurityGAOnly(t *testing.T) {
Features: utilfeature.DefaultFeatureGate,
}
podsecuritytest.Run(t, opts)
ValidatePluginMetrics(t, opts.ClientConfig)
}
func TestPodSecurityWebhook(t *testing.T) {
@@ -125,6 +132,8 @@ func TestPodSecurityWebhook(t *testing.T) {
ExemptRuntimeClasses: []string{},
}
podsecuritytest.Run(t, opts)
ValidateWebhookMetrics(t, webhookAddr)
}
func startPodSecurityServer(t *testing.T) *kubeapiservertesting.TestServer {
@@ -285,3 +294,52 @@ func installWebhook(t *testing.T, clientConfig *rest.Config, addr string) error
return nil
}
func ValidatePluginMetrics(t *testing.T, clientConfig *rest.Config) {
client, err := kubernetes.NewForConfig(clientConfig)
if err != nil {
t.Fatalf("Error creating client: %v", err)
}
ctx := context.Background()
data, err := client.CoreV1().RESTClient().Get().AbsPath("metrics").DoRaw(ctx)
if err != nil {
t.Fatalf("Failed to read metrics: %v", err)
}
validateMetrics(t, data)
}
func ValidateWebhookMetrics(t *testing.T, webhookAddr string) {
endpoint := &url.URL{
Scheme: "https",
Host: webhookAddr,
Path: "/metrics",
}
client := &http.Client{Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}}
resp, err := client.Get(endpoint.String())
if err != nil {
t.Fatalf("Failed to fetch metrics from %s: %v", endpoint.String(), err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
t.Fatalf("Non-200 response trying to scrape metrics from %s: %v", endpoint.String(), resp)
}
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
t.Fatalf("Unable to read metrics response: %v", err)
}
validateMetrics(t, data)
}
func validateMetrics(t *testing.T, rawMetrics []byte) {
metrics := testutil.NewMetrics()
if err := testutil.ParseMetrics(string(rawMetrics), &metrics); err != nil {
t.Fatalf("Failed to parse metrics: %v", err)
}
if err := testutil.ValidateMetrics(metrics, "pod_security_evaluations_total",
"decision", "policy_level", "policy_version", "mode", "request_operation", "resource", "subresource"); err != nil {
t.Fatalf("Metric validation failed: %v", err)
}
}