mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-22 11:21:47 +00:00
Merge pull request #108810 from enj/enj/i/create_token_duration
kubectl create token: use duration instead of expiration seconds
This commit is contained in:
commit
b383035ca3
@ -20,6 +20,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
@ -35,6 +36,7 @@ import (
|
||||
"k8s.io/kubectl/pkg/util"
|
||||
"k8s.io/kubectl/pkg/util/templates"
|
||||
"k8s.io/kubectl/pkg/util/term"
|
||||
"k8s.io/utils/pointer"
|
||||
)
|
||||
|
||||
// TokenOptions is the data required to perform a token request operation.
|
||||
@ -57,8 +59,8 @@ type TokenOptions struct {
|
||||
// Audiences indicate the valid audiences for the requested token. If unset, defaults to the Kubernetes API server audiences.
|
||||
Audiences []string
|
||||
|
||||
// ExpirationSeconds is the requested token lifetime. Optional.
|
||||
ExpirationSeconds int64
|
||||
// Duration is the requested token lifetime. Optional.
|
||||
Duration time.Duration
|
||||
|
||||
// CoreClient is the API client used to request the token. Required.
|
||||
CoreClient corev1client.CoreV1Interface
|
||||
@ -78,7 +80,7 @@ var (
|
||||
kubectl create token myapp --namespace myns
|
||||
|
||||
# Request a token with a custom expiration
|
||||
kubectl create token myapp --expiration-seconds 600
|
||||
kubectl create token myapp --duration 10m
|
||||
|
||||
# Request a token with a custom audience
|
||||
kubectl create token myapp --audience https://example.com
|
||||
@ -134,7 +136,7 @@ func NewCmdCreateToken(f cmdutil.Factory, ioStreams genericclioptions.IOStreams)
|
||||
|
||||
cmd.Flags().StringArrayVar(&o.Audiences, "audience", o.Audiences, "Audience of the requested token. If unset, defaults to requesting a token for use with the Kubernetes API server. May be repeated to request a token valid for multiple audiences.")
|
||||
|
||||
cmd.Flags().Int64Var(&o.ExpirationSeconds, "expiration-seconds", o.ExpirationSeconds, "Requested lifetime of the issued token. The server may return a token with a longer or shorter lifetime.")
|
||||
cmd.Flags().DurationVar(&o.Duration, "duration", o.Duration, "Requested lifetime of the issued token. The server may return a token with a longer or shorter lifetime.")
|
||||
|
||||
cmd.Flags().StringVar(&o.BoundObjectKind, "bound-object-kind", o.BoundObjectKind, "Kind of an object to bind the token to. "+
|
||||
"Supported kinds are "+strings.Join(sets.StringKeySet(boundObjectKindToAPIVersion).List(), ", ")+". "+
|
||||
@ -192,8 +194,11 @@ func (o *TokenOptions) Validate() error {
|
||||
if len(o.Namespace) == 0 {
|
||||
return fmt.Errorf("--namespace is required")
|
||||
}
|
||||
if o.ExpirationSeconds < 0 {
|
||||
return fmt.Errorf("--expiration-seconds must be positive")
|
||||
if o.Duration < 0 {
|
||||
return fmt.Errorf("--duration must be positive")
|
||||
}
|
||||
if o.Duration%time.Second != 0 {
|
||||
return fmt.Errorf("--duration cannot be expressed in units less than seconds")
|
||||
}
|
||||
for _, aud := range o.Audiences {
|
||||
if len(aud) == 0 {
|
||||
@ -227,8 +232,8 @@ func (o *TokenOptions) Run() error {
|
||||
Audiences: o.Audiences,
|
||||
},
|
||||
}
|
||||
if o.ExpirationSeconds > 0 {
|
||||
request.Spec.ExpirationSeconds = &o.ExpirationSeconds
|
||||
if o.Duration > 0 {
|
||||
request.Spec.ExpirationSeconds = pointer.Int64(int64(o.Duration / time.Second))
|
||||
}
|
||||
if len(o.BoundObjectKind) > 0 {
|
||||
request.Spec.BoundObjectRef = &authenticationv1.BoundObjectReference{
|
||||
|
@ -22,8 +22,8 @@ import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"k8s.io/utils/pointer"
|
||||
@ -44,14 +44,14 @@ func TestCreateToken(t *testing.T) {
|
||||
tests := []struct {
|
||||
test string
|
||||
|
||||
name string
|
||||
namespace string
|
||||
output string
|
||||
boundObjectKind string
|
||||
boundObjectName string
|
||||
boundObjectUID string
|
||||
audiences []string
|
||||
expirationSeconds int
|
||||
name string
|
||||
namespace string
|
||||
output string
|
||||
boundObjectKind string
|
||||
boundObjectName string
|
||||
boundObjectUID string
|
||||
audiences []string
|
||||
duration time.Duration
|
||||
|
||||
serverResponseToken string
|
||||
serverResponseError string
|
||||
@ -183,16 +183,22 @@ status:
|
||||
},
|
||||
|
||||
{
|
||||
test: "invalid expiration",
|
||||
name: "mysa",
|
||||
expirationSeconds: -1,
|
||||
expectStderr: `error: --expiration-seconds must be positive`,
|
||||
test: "invalid duration",
|
||||
name: "mysa",
|
||||
duration: -1,
|
||||
expectStderr: `error: --duration must be positive`,
|
||||
},
|
||||
{
|
||||
test: "valid expiration",
|
||||
test: "invalid duration unit",
|
||||
name: "mysa",
|
||||
duration: time.Microsecond,
|
||||
expectStderr: `error: --duration cannot be expressed in units less than seconds`,
|
||||
},
|
||||
{
|
||||
test: "valid duration",
|
||||
name: "mysa",
|
||||
|
||||
expirationSeconds: 1000,
|
||||
duration: 1000 * time.Second,
|
||||
|
||||
expectRequestPath: "/api/v1/namespaces/test/serviceaccounts/mysa/token",
|
||||
expectTokenRequest: &authenticationv1.TokenRequest{
|
||||
@ -310,8 +316,8 @@ status:
|
||||
for _, aud := range test.audiences {
|
||||
cmd.Flags().Set("audience", aud)
|
||||
}
|
||||
if test.expirationSeconds != 0 {
|
||||
cmd.Flags().Set("expiration-seconds", strconv.Itoa(test.expirationSeconds))
|
||||
if test.duration != 0 {
|
||||
cmd.Flags().Set("duration", test.duration.String())
|
||||
}
|
||||
cmd.Run(cmd, []string{test.name})
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user