mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-14 18:53:35 +00:00
vendor updates
This commit is contained in:
186
vendor/k8s.io/kubernetes/pkg/serviceaccount/claims.go
generated
vendored
Normal file
186
vendor/k8s.io/kubernetes/pkg/serviceaccount/claims.go
generated
vendored
Normal file
@ -0,0 +1,186 @@
|
||||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package serviceaccount
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
apiserverserviceaccount "k8s.io/apiserver/pkg/authentication/serviceaccount"
|
||||
"k8s.io/kubernetes/pkg/apis/core"
|
||||
|
||||
"gopkg.in/square/go-jose.v2/jwt"
|
||||
)
|
||||
|
||||
// time.Now stubbed out to allow testing
|
||||
var now = time.Now
|
||||
|
||||
type privateClaims struct {
|
||||
Kubernetes kubernetes `json:"kubernetes.io,omitempty"`
|
||||
}
|
||||
|
||||
type kubernetes struct {
|
||||
Namespace string `json:"namespace,omitempty"`
|
||||
Svcacct ref `json:"serviceaccount,omitempty"`
|
||||
Pod *ref `json:"pod,omitempty"`
|
||||
Secret *ref `json:"secret,omitempty"`
|
||||
}
|
||||
|
||||
type ref struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
UID string `json:"uid,omitempty"`
|
||||
}
|
||||
|
||||
func Claims(sa core.ServiceAccount, pod *core.Pod, secret *core.Secret, expirationSeconds int64, audience []string) (*jwt.Claims, interface{}) {
|
||||
now := now()
|
||||
sc := &jwt.Claims{
|
||||
Subject: apiserverserviceaccount.MakeUsername(sa.Namespace, sa.Name),
|
||||
Audience: jwt.Audience(audience),
|
||||
IssuedAt: jwt.NewNumericDate(now),
|
||||
NotBefore: jwt.NewNumericDate(now),
|
||||
Expiry: jwt.NewNumericDate(now.Add(time.Duration(expirationSeconds) * time.Second)),
|
||||
}
|
||||
pc := &privateClaims{
|
||||
Kubernetes: kubernetes{
|
||||
Namespace: sa.Namespace,
|
||||
Svcacct: ref{
|
||||
Name: sa.Name,
|
||||
UID: string(sa.UID),
|
||||
},
|
||||
},
|
||||
}
|
||||
switch {
|
||||
case pod != nil:
|
||||
pc.Kubernetes.Pod = &ref{
|
||||
Name: pod.Name,
|
||||
UID: string(pod.UID),
|
||||
}
|
||||
case secret != nil:
|
||||
pc.Kubernetes.Secret = &ref{
|
||||
Name: secret.Name,
|
||||
UID: string(secret.UID),
|
||||
}
|
||||
}
|
||||
return sc, pc
|
||||
}
|
||||
|
||||
func NewValidator(audiences []string, getter ServiceAccountTokenGetter) Validator {
|
||||
return &validator{
|
||||
auds: audiences,
|
||||
getter: getter,
|
||||
}
|
||||
}
|
||||
|
||||
type validator struct {
|
||||
auds []string
|
||||
getter ServiceAccountTokenGetter
|
||||
}
|
||||
|
||||
var _ = Validator(&validator{})
|
||||
|
||||
func (v *validator) Validate(_ string, public *jwt.Claims, privateObj interface{}) (string, string, string, error) {
|
||||
private, ok := privateObj.(*privateClaims)
|
||||
if !ok {
|
||||
glog.Errorf("jwt validator expected private claim of type *privateClaims but got: %T", privateObj)
|
||||
return "", "", "", errors.New("Token could not be validated.")
|
||||
}
|
||||
err := public.Validate(jwt.Expected{
|
||||
Time: now(),
|
||||
})
|
||||
switch {
|
||||
case err == nil:
|
||||
case err == jwt.ErrExpired:
|
||||
return "", "", "", errors.New("Token has expired.")
|
||||
default:
|
||||
glog.Errorf("unexpected validation error: %T", err)
|
||||
return "", "", "", errors.New("Token could not be validated.")
|
||||
}
|
||||
|
||||
var audValid bool
|
||||
|
||||
for _, aud := range v.auds {
|
||||
audValid = public.Audience.Contains(aud)
|
||||
if audValid {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !audValid {
|
||||
return "", "", "", errors.New("Token is invalid for this audience.")
|
||||
}
|
||||
|
||||
namespace := private.Kubernetes.Namespace
|
||||
saref := private.Kubernetes.Svcacct
|
||||
podref := private.Kubernetes.Pod
|
||||
secref := private.Kubernetes.Secret
|
||||
// Make sure service account still exists (name and UID)
|
||||
serviceAccount, err := v.getter.GetServiceAccount(namespace, saref.Name)
|
||||
if err != nil {
|
||||
glog.V(4).Infof("Could not retrieve service account %s/%s: %v", namespace, saref.Name, err)
|
||||
return "", "", "", err
|
||||
}
|
||||
if serviceAccount.DeletionTimestamp != nil {
|
||||
glog.V(4).Infof("Service account has been deleted %s/%s", namespace, saref.Name)
|
||||
return "", "", "", fmt.Errorf("ServiceAccount %s/%s has been deleted", namespace, saref.Name)
|
||||
}
|
||||
if string(serviceAccount.UID) != saref.UID {
|
||||
glog.V(4).Infof("Service account UID no longer matches %s/%s: %q != %q", namespace, saref.Name, string(serviceAccount.UID), saref.UID)
|
||||
return "", "", "", fmt.Errorf("ServiceAccount UID (%s) does not match claim (%s)", serviceAccount.UID, saref.UID)
|
||||
}
|
||||
|
||||
if secref != nil {
|
||||
// Make sure token hasn't been invalidated by deletion of the secret
|
||||
secret, err := v.getter.GetSecret(namespace, secref.Name)
|
||||
if err != nil {
|
||||
glog.V(4).Infof("Could not retrieve bound secret %s/%s for service account %s/%s: %v", namespace, secref.Name, namespace, saref.Name, err)
|
||||
return "", "", "", errors.New("Token has been invalidated")
|
||||
}
|
||||
if secret.DeletionTimestamp != nil {
|
||||
glog.V(4).Infof("Bound secret is deleted and awaiting removal: %s/%s for service account %s/%s", namespace, secref.Name, namespace, saref.Name)
|
||||
return "", "", "", errors.New("Token has been invalidated")
|
||||
}
|
||||
if string(secref.UID) != secref.UID {
|
||||
glog.V(4).Infof("Secret UID no longer matches %s/%s: %q != %q", namespace, secref.Name, string(serviceAccount.UID), secref.UID)
|
||||
return "", "", "", fmt.Errorf("Secret UID (%s) does not match claim (%s)", secret.UID, secref.UID)
|
||||
}
|
||||
}
|
||||
|
||||
if podref != nil {
|
||||
// Make sure token hasn't been invalidated by deletion of the pod
|
||||
pod, err := v.getter.GetPod(namespace, podref.Name)
|
||||
if err != nil {
|
||||
glog.V(4).Infof("Could not retrieve bound secret %s/%s for service account %s/%s: %v", namespace, podref.Name, namespace, saref.Name, err)
|
||||
return "", "", "", errors.New("Token has been invalidated")
|
||||
}
|
||||
if pod.DeletionTimestamp != nil {
|
||||
glog.V(4).Infof("Bound pod is deleted and awaiting removal: %s/%s for service account %s/%s", namespace, podref.Name, namespace, saref.Name)
|
||||
return "", "", "", errors.New("Token has been invalidated")
|
||||
}
|
||||
if string(podref.UID) != podref.UID {
|
||||
glog.V(4).Infof("Pod UID no longer matches %s/%s: %q != %q", namespace, podref.Name, string(serviceAccount.UID), podref.UID)
|
||||
return "", "", "", fmt.Errorf("Pod UID (%s) does not match claim (%s)", pod.UID, podref.UID)
|
||||
}
|
||||
}
|
||||
|
||||
return private.Kubernetes.Namespace, private.Kubernetes.Svcacct.Name, private.Kubernetes.Svcacct.UID, nil
|
||||
}
|
||||
|
||||
func (v *validator) NewPrivateClaims() interface{} {
|
||||
return &privateClaims{}
|
||||
}
|
Reference in New Issue
Block a user