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 }