github.com/kubernetes-incubator/kube-aws@v0.16.4/credential/encrypted_assets_test.go (about)

     1  package credential
     2  
     3  import (
     4  	"testing"
     5  
     6  	"encoding/base64"
     7  	"os"
     8  	"path/filepath"
     9  	"reflect"
    10  	"strings"
    11  
    12  	"fmt"
    13  
    14  	"github.com/aws/aws-sdk-go/service/kms"
    15  	"github.com/kubernetes-incubator/kube-aws/test/helper"
    16  )
    17  
    18  var goodNetworkingConfigs = []string{
    19  	``, //Tests validity of default network config values
    20  	`
    21  vpcCIDR: 10.4.3.0/24
    22  instanceCIDR: 10.4.3.0/24
    23  podCIDR: 172.4.0.0/16
    24  serviceCIDR: 172.5.0.0/16
    25  dnsServiceIP: 172.5.100.101
    26  `, `
    27  vpcCIDR: 10.4.0.0/16
    28  instanceCIDR: 10.4.3.0/24
    29  podCIDR: 10.6.0.0/16
    30  serviceCIDR: 10.5.0.0/16
    31  dnsServiceIP: 10.5.100.101
    32  `, `
    33  vpcId: vpc-xxxxx
    34  routeTableId: rtb-xxxxxx
    35  `, `
    36  vpcId: vpc-xxxxx
    37  `, `
    38  createRecordSet: false
    39  hostedZoneId: ""
    40  `, `
    41  createRecordSet: true
    42  recordSetTTL: 400
    43  hostedZoneId: "XXXXXXXXXXX"
    44  `, `
    45  createRecordSet: true
    46  hostedZoneId: "XXXXXXXXXXX"
    47  `,
    48  }
    49  
    50  type dummyEncryptService struct{}
    51  
    52  var numEncryption = 0
    53  
    54  func (d *dummyEncryptService) Encrypt(input *kms.EncryptInput) (*kms.EncryptOutput, error) {
    55  	output := kms.EncryptOutput{
    56  		CiphertextBlob: []byte(fmt.Sprintf("%s%d", string(input.Plaintext), numEncryption)),
    57  	}
    58  	numEncryption += 1
    59  	return &output, nil
    60  }
    61  
    62  func TestReadOrCreateCompactAssets(t *testing.T) {
    63  	helper.WithDummyCredentials(func(dir string) {
    64  		kmsConfig := NewKMSConfig("keyarn", &dummyEncryptService{}, nil)
    65  
    66  		// See https://github.com/kubernetes-incubator/kube-aws/issues/107
    67  		t.Run("CachedToPreventUnnecessaryNodeReplacement", func(t *testing.T) {
    68  			created, err := ReadOrCreateCompactAssets(dir, true, true, kmsConfig)
    69  
    70  			if err != nil {
    71  				t.Errorf("failed to read or update compact assets in %s : %v", dir, err)
    72  				t.FailNow()
    73  			}
    74  
    75  			// This depends on TestDummyEncryptService which ensures dummy encrypt service to produce different ciphertext for each encryption
    76  			// created == read means that encrypted assets were loaded from cached files named *.pem.enc, instead of re-encrypting raw assets named *.pem files
    77  			// TODO Use some kind of mocking framework for tests like this
    78  			read, err := ReadOrCreateCompactAssets(dir, true, true, kmsConfig)
    79  
    80  			if err != nil {
    81  				t.Errorf("failed to read or update compact assets in %s : %v", dir, err)
    82  				t.FailNow()
    83  			}
    84  
    85  			if !reflect.DeepEqual(created, read) {
    86  				t.Errorf(`failed to content encrypted assets.
    87  	encrypted assets must not change after their first creation but they did change:
    88  	created = %v
    89  	read = %v`, created, read)
    90  			}
    91  		})
    92  
    93  		t.Run("RemoveFilesToRegenerate", func(t *testing.T) {
    94  			original, err := ReadOrCreateCompactAssets(dir, true, true, kmsConfig)
    95  
    96  			if err != nil {
    97  				t.Errorf("failed to read the original encrypted assets : %v", err)
    98  				t.FailNow()
    99  			}
   100  
   101  			files := []string{
   102  				"admin-key.pem.enc", "worker-key.pem.enc", "apiserver-key.pem.enc",
   103  				"etcd-key.pem.enc", "etcd-client-key.pem.enc", "worker-ca-key.pem.enc",
   104  				"kube-controller-manager-key.pem.enc", "kube-scheduler-key.pem.enc",
   105  				"apiserver-aggregator-key.pem.enc",
   106  			}
   107  
   108  			for _, filename := range files {
   109  				if err := os.Remove(filepath.Join(dir, filename)); err != nil {
   110  					t.Errorf("failed to remove %s for test setup : %v", filename, err)
   111  					t.FailNow()
   112  				}
   113  			}
   114  
   115  			regenerated, err := ReadOrCreateCompactAssets(dir, true, true, kmsConfig)
   116  
   117  			if err != nil {
   118  				t.Errorf("failed to read the regenerated encrypted assets : %v", err)
   119  				t.FailNow()
   120  			}
   121  
   122  			for _, v := range [][]string{
   123  				{"AdminCert", original.AdminCert, regenerated.AdminCert},
   124  				{"CACert", original.CACert, regenerated.CACert},
   125  				{"WorkerCert", original.WorkerCert, regenerated.WorkerCert},
   126  				{"APIServerCert", original.APIServerCert, regenerated.APIServerCert},
   127  				{"KubeControllerManagerCert", original.KubeControllerManagerCert, regenerated.KubeControllerManagerCert},
   128  				{"KubeSchedulerCert", original.KubeSchedulerCert, regenerated.KubeSchedulerCert},
   129  				{"EtcdClientCert", original.EtcdClientCert, regenerated.EtcdClientCert},
   130  				{"EtcdCert", original.EtcdCert, regenerated.EtcdCert},
   131  				{"APIServerAggregatorCert", original.APIServerAggregatorCert, regenerated.APIServerAggregatorCert},
   132  			} {
   133  				if v[1] != v[2] {
   134  					t.Errorf("%s must NOT change but it did : original = %v, regenrated = %v ", v[0], v[1], v[2])
   135  				}
   136  			}
   137  
   138  			for _, v := range [][]string{
   139  				{"AdminKey", original.AdminKey, regenerated.AdminKey},
   140  				{"WorkerCAKey", original.WorkerCAKey, regenerated.WorkerCAKey},
   141  				{"WorkerKey", original.WorkerKey, regenerated.WorkerKey},
   142  				{"APIServerKey", original.APIServerKey, regenerated.APIServerKey},
   143  				{"KubeControllerManagerKey", original.KubeControllerManagerKey, regenerated.KubeControllerManagerKey},
   144  				{"KubeSchedulerKey", original.KubeSchedulerKey, regenerated.KubeSchedulerKey},
   145  				{"EtcdClientKey", original.EtcdClientKey, regenerated.EtcdClientKey},
   146  				{"EtcdKey", original.EtcdKey, regenerated.EtcdKey},
   147  				{"APIServerAggregatorKey", original.APIServerAggregatorKey, regenerated.APIServerAggregatorKey},
   148  			} {
   149  				if v[1] == v[2] {
   150  					t.Errorf("%s must change but it didn't : original = %v, regenrated = %v ", v[0], v[1], v[2])
   151  				}
   152  			}
   153  			if reflect.DeepEqual(original, regenerated) {
   154  				t.Errorf(`unexpecteed data contained in (possibly) regenerated encrypted assets.
   155  	encrypted assets must change after regeneration but they didn't:
   156  	original = %v
   157  	regenerated = %v`, original, regenerated)
   158  			}
   159  		})
   160  	})
   161  }
   162  
   163  func TestReadOrCreateUnEncryptedCompactAssets(t *testing.T) {
   164  	run := func(dir string, caKeyRequiredOnController bool, t *testing.T) {
   165  		t.Run("CachedToPreventUnnecessaryNodeReplacementOnUnencrypted", func(t *testing.T) {
   166  			created, err := ReadOrCreateUnencryptedCompactAssets(dir, true, caKeyRequiredOnController)
   167  
   168  			if err != nil {
   169  				t.Errorf("failed to read or update compact assets in %s : %v", dir, err)
   170  			}
   171  
   172  			read, err := ReadOrCreateUnencryptedCompactAssets(dir, true, caKeyRequiredOnController)
   173  
   174  			if err != nil {
   175  				t.Errorf("failed to read or update compact assets in %s : %v", dir, err)
   176  			}
   177  
   178  			if !reflect.DeepEqual(created, read) {
   179  				t.Errorf(`failed to content unencrypted assets.
   180  		unencrypted assets must not change after their first creation but they did change:
   181  		created = %v
   182  		read = %v`, created, read)
   183  			}
   184  		})
   185  	}
   186  
   187  	t.Run("WithDummyCredentialsButCAKey", func(t *testing.T) {
   188  		helper.WithDummyCredentialsButCAKey(func(dir string) {
   189  			run(dir, false, t)
   190  		})
   191  	})
   192  	t.Run("WithDummyCredentials", func(t *testing.T) {
   193  		helper.WithDummyCredentials(func(dir string) {
   194  			run(dir, true, t)
   195  		})
   196  	})
   197  }
   198  
   199  func TestRandomTokenString(t *testing.T) {
   200  	randomToken, err := RandomTokenString()
   201  	if err != nil {
   202  		t.Errorf("failed to generate a Kubelet bootstrap token: %v", err)
   203  	}
   204  	if strings.Index(randomToken, ",") >= 0 {
   205  		t.Errorf("random token not expect to contain a comma: %v", randomToken)
   206  	}
   207  
   208  	b, err := base64.StdEncoding.DecodeString(randomToken)
   209  	if err != nil {
   210  		t.Errorf("failed to decode base64 token string: %v", err)
   211  	}
   212  	if len(b) != 32 {
   213  		t.Errorf("expected token to be 256 bits long, but was %d", len(b))
   214  	}
   215  }
   216  
   217  func TestHasAuthTokens(t *testing.T) {
   218  	testCases := []struct {
   219  		authTokens string
   220  		expected   bool
   221  	}{
   222  		// Without auth tokens
   223  		{
   224  			authTokens: "",
   225  			expected:   false,
   226  		},
   227  
   228  		// With auth tokens
   229  		{
   230  			authTokens: "contents",
   231  			expected:   true,
   232  		},
   233  	}
   234  
   235  	for _, testCase := range testCases {
   236  		asset := &CompactAssets{
   237  			AuthTokens: testCase.authTokens,
   238  		}
   239  
   240  		actual := asset.HasAuthTokens()
   241  		if actual != testCase.expected {
   242  			t.Errorf("Expected HasAuthTokens to be %v, but was %v", testCase.expected, actual)
   243  		}
   244  	}
   245  }
   246  
   247  func TestHasTLSBootstrapToken(t *testing.T) {
   248  	testCases := []struct {
   249  		tlsBootstrapToken string
   250  		expected          bool
   251  	}{
   252  		// Without TLS bootstrap token
   253  		{
   254  			tlsBootstrapToken: "",
   255  			expected:          false,
   256  		},
   257  
   258  		// With TLS bootstrap token
   259  		{
   260  			tlsBootstrapToken: "contents",
   261  			expected:          true,
   262  		},
   263  	}
   264  
   265  	for _, testCase := range testCases {
   266  		asset := &CompactAssets{
   267  			TLSBootstrapToken: testCase.tlsBootstrapToken,
   268  		}
   269  
   270  		actual := asset.HasTLSBootstrapToken()
   271  		if actual != testCase.expected {
   272  			t.Errorf("Expected HasTLSBootstrapToken to be %v, but was %v", testCase.expected, actual)
   273  		}
   274  	}
   275  }