...

Source file src/k8s.io/kubernetes/pkg/controller/bootstrap/util_test.go

Documentation: k8s.io/kubernetes/pkg/controller/bootstrap

     1  /*
     2  Copyright 2016 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package bootstrap
    18  
    19  import (
    20  	"testing"
    21  	"time"
    22  
    23  	"k8s.io/api/core/v1"
    24  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    25  	bootstrapapi "k8s.io/cluster-bootstrap/token/api"
    26  	"k8s.io/klog/v2/ktesting"
    27  )
    28  
    29  const (
    30  	givenTokenID     = "abc123"
    31  	givenTokenID2    = "def456"
    32  	givenTokenSecret = "tokenSecret"
    33  )
    34  
    35  func timeString(delta time.Duration) string {
    36  	return time.Now().Add(delta).Format(time.RFC3339)
    37  }
    38  
    39  func TestValidateSecretForSigning(t *testing.T) {
    40  	cases := []struct {
    41  		description string
    42  		tokenID     string
    43  		tokenSecret string
    44  		okToSign    string
    45  		expiration  string
    46  		valid       bool
    47  	}{
    48  		{
    49  			"Signing token with no exp",
    50  			givenTokenID, givenTokenSecret, "true", "", true,
    51  		},
    52  		{
    53  			"Signing token with valid exp",
    54  			givenTokenID, givenTokenSecret, "true", timeString(time.Hour), true,
    55  		},
    56  		{
    57  			"Expired signing token",
    58  			givenTokenID, givenTokenSecret, "true", timeString(-time.Hour), false,
    59  		},
    60  		{
    61  			"Signing token with bad exp",
    62  			givenTokenID, givenTokenSecret, "true", "garbage", false,
    63  		},
    64  		{
    65  			"Signing token without signing bit",
    66  			givenTokenID, givenTokenSecret, "", "garbage", false,
    67  		},
    68  		{
    69  			"Signing token with bad signing bit",
    70  			givenTokenID, givenTokenSecret, "", "", false,
    71  		},
    72  		{
    73  			"Signing token with no ID",
    74  			"", givenTokenSecret, "true", "", false,
    75  		},
    76  		{
    77  			"Signing token with no secret",
    78  			givenTokenID, "", "true", "", false,
    79  		},
    80  	}
    81  
    82  	for _, tc := range cases {
    83  		t.Run(tc.description, func(t *testing.T) {
    84  			_, ctx := ktesting.NewTestContext(t)
    85  			secret := &v1.Secret{
    86  				ObjectMeta: metav1.ObjectMeta{
    87  					Namespace:       metav1.NamespaceSystem,
    88  					Name:            bootstrapapi.BootstrapTokenSecretPrefix + givenTokenID,
    89  					ResourceVersion: "1",
    90  				},
    91  				Type: bootstrapapi.SecretTypeBootstrapToken,
    92  				Data: map[string][]byte{
    93  					bootstrapapi.BootstrapTokenIDKey:           []byte(tc.tokenID),
    94  					bootstrapapi.BootstrapTokenSecretKey:       []byte(tc.tokenSecret),
    95  					bootstrapapi.BootstrapTokenUsageSigningKey: []byte(tc.okToSign),
    96  					bootstrapapi.BootstrapTokenExpirationKey:   []byte(tc.expiration),
    97  				},
    98  			}
    99  
   100  			tokenID, tokenSecret, ok := validateSecretForSigning(ctx, secret)
   101  			if ok != tc.valid {
   102  				t.Errorf("Unexpected validation failure. Expected %v, got %v", tc.valid, ok)
   103  			}
   104  			if ok {
   105  				if tokenID != tc.tokenID {
   106  					t.Errorf("Unexpected Token ID. Expected %q, got %q", givenTokenID, tokenID)
   107  				}
   108  				if tokenSecret != tc.tokenSecret {
   109  					t.Errorf("Unexpected Token Secret. Expected %q, got %q", givenTokenSecret, tokenSecret)
   110  				}
   111  			}
   112  		})
   113  	}
   114  
   115  }
   116  
   117  func TestValidateSecret(t *testing.T) {
   118  	_, ctx := ktesting.NewTestContext(t)
   119  	secret := &v1.Secret{
   120  		ObjectMeta: metav1.ObjectMeta{
   121  			Namespace:       metav1.NamespaceSystem,
   122  			Name:            bootstrapapi.BootstrapTokenSecretPrefix + givenTokenID,
   123  			ResourceVersion: "1",
   124  		},
   125  		Type: bootstrapapi.SecretTypeBootstrapToken,
   126  		Data: map[string][]byte{
   127  			bootstrapapi.BootstrapTokenIDKey:           []byte(givenTokenID),
   128  			bootstrapapi.BootstrapTokenSecretKey:       []byte(givenTokenSecret),
   129  			bootstrapapi.BootstrapTokenUsageSigningKey: []byte("true"),
   130  		},
   131  	}
   132  
   133  	tokenID, tokenSecret, ok := validateSecretForSigning(ctx, secret)
   134  	if !ok {
   135  		t.Errorf("Unexpected validation failure.")
   136  	}
   137  	if tokenID != givenTokenID {
   138  		t.Errorf("Unexpected Token ID. Expected %q, got %q", givenTokenID, tokenID)
   139  	}
   140  	if tokenSecret != givenTokenSecret {
   141  		t.Errorf("Unexpected Token Secret. Expected %q, got %q", givenTokenSecret, tokenSecret)
   142  	}
   143  }
   144  
   145  func TestBadSecretName(t *testing.T) {
   146  	_, ctx := ktesting.NewTestContext(t)
   147  	secret := &v1.Secret{
   148  		ObjectMeta: metav1.ObjectMeta{
   149  			Namespace:       metav1.NamespaceSystem,
   150  			Name:            givenTokenID,
   151  			ResourceVersion: "1",
   152  		},
   153  		Type: bootstrapapi.SecretTypeBootstrapToken,
   154  		Data: map[string][]byte{
   155  			bootstrapapi.BootstrapTokenIDKey:           []byte(givenTokenID),
   156  			bootstrapapi.BootstrapTokenSecretKey:       []byte(givenTokenSecret),
   157  			bootstrapapi.BootstrapTokenUsageSigningKey: []byte("true"),
   158  		},
   159  	}
   160  
   161  	_, _, ok := validateSecretForSigning(ctx, secret)
   162  	if ok {
   163  		t.Errorf("Token validation should fail with bad name")
   164  	}
   165  }
   166  
   167  func TestMismatchSecretName(t *testing.T) {
   168  	_, ctx := ktesting.NewTestContext(t)
   169  	secret := &v1.Secret{
   170  		ObjectMeta: metav1.ObjectMeta{
   171  			Namespace:       metav1.NamespaceSystem,
   172  			Name:            bootstrapapi.BootstrapTokenSecretPrefix + givenTokenID2,
   173  			ResourceVersion: "1",
   174  		},
   175  		Type: bootstrapapi.SecretTypeBootstrapToken,
   176  		Data: map[string][]byte{
   177  			bootstrapapi.BootstrapTokenIDKey:           []byte(givenTokenID),
   178  			bootstrapapi.BootstrapTokenSecretKey:       []byte(givenTokenSecret),
   179  			bootstrapapi.BootstrapTokenUsageSigningKey: []byte("true"),
   180  		},
   181  	}
   182  
   183  	_, _, ok := validateSecretForSigning(ctx, secret)
   184  	if ok {
   185  		t.Errorf("Token validation should fail with mismatched name")
   186  	}
   187  }
   188  

View as plain text