...

Source file src/k8s.io/kubernetes/cmd/kubeadm/app/componentconfigs/checksums_test.go

Documentation: k8s.io/kubernetes/cmd/kubeadm/app/componentconfigs

     1  /*
     2  Copyright 2019 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 componentconfigs
    18  
    19  import (
    20  	"testing"
    21  
    22  	v1 "k8s.io/api/core/v1"
    23  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    24  
    25  	"k8s.io/kubernetes/cmd/kubeadm/app/constants"
    26  )
    27  
    28  var checksumTestCases = []struct {
    29  	desc      string
    30  	configMap *v1.ConfigMap
    31  	checksum  string
    32  }{
    33  	{
    34  		desc:     "checksum is calculated using both data and binaryData",
    35  		checksum: "sha256:c8f8b724728a6d6684106e5e64e94ce811c9965d19dd44dd073cf86cf43bc238",
    36  		configMap: &v1.ConfigMap{
    37  			Data: map[string]string{
    38  				"foo": "bar",
    39  			},
    40  			BinaryData: map[string][]byte{
    41  				"bar": []byte("baz"),
    42  			},
    43  		},
    44  	},
    45  	{
    46  		desc:     "config keys have no effect on the checksum",
    47  		checksum: "sha256:c8f8b724728a6d6684106e5e64e94ce811c9965d19dd44dd073cf86cf43bc238",
    48  		configMap: &v1.ConfigMap{
    49  			Data: map[string]string{
    50  				"foo2": "bar",
    51  			},
    52  			BinaryData: map[string][]byte{
    53  				"bar2": []byte("baz"),
    54  			},
    55  		},
    56  	},
    57  	{
    58  		desc:     "metadata fields have no effect on the checksum",
    59  		checksum: "sha256:c8f8b724728a6d6684106e5e64e94ce811c9965d19dd44dd073cf86cf43bc238",
    60  		configMap: &v1.ConfigMap{
    61  			ObjectMeta: metav1.ObjectMeta{
    62  				Name:      "le-config",
    63  				Namespace: "le-namespace",
    64  				Labels: map[string]string{
    65  					"label1": "value1",
    66  					"label2": "value2",
    67  				},
    68  				Annotations: map[string]string{
    69  					"annotation1": "value1",
    70  					"annotation2": "value2",
    71  				},
    72  			},
    73  			Data: map[string]string{
    74  				"foo": "bar",
    75  			},
    76  			BinaryData: map[string][]byte{
    77  				"bar": []byte("baz"),
    78  			},
    79  		},
    80  	},
    81  	{
    82  		desc:     "checksum can be calculated without binaryData",
    83  		checksum: "sha256:fcde2b2edba56bf408601fb721fe9b5c338d10ee429ea04fae5511b68fbf8fb9",
    84  		configMap: &v1.ConfigMap{
    85  			Data: map[string]string{
    86  				"foo": "bar",
    87  			},
    88  		},
    89  	},
    90  	{
    91  		desc:     "checksum can be calculated without data",
    92  		checksum: "sha256:baa5a0964d3320fbc0c6a922140453c8513ea24ab8fd0577034804a967248096",
    93  		configMap: &v1.ConfigMap{
    94  			BinaryData: map[string][]byte{
    95  				"bar": []byte("baz"),
    96  			},
    97  		},
    98  	},
    99  }
   100  
   101  func TestChecksumForConfigMap(t *testing.T) {
   102  	for _, test := range checksumTestCases {
   103  		t.Run(test.desc, func(t *testing.T) {
   104  			got := ChecksumForConfigMap(test.configMap)
   105  			if got != test.checksum {
   106  				t.Errorf("checksum mismatch - got %q, expected %q", got, test.checksum)
   107  			}
   108  		})
   109  	}
   110  }
   111  
   112  func TestSignConfigMap(t *testing.T) {
   113  	for _, test := range checksumTestCases {
   114  		t.Run(test.desc, func(t *testing.T) {
   115  			target := test.configMap.DeepCopy()
   116  			SignConfigMap(target)
   117  
   118  			// Verify that we have a correct annotation
   119  			signature, ok := target.Annotations[constants.ComponentConfigHashAnnotationKey]
   120  			if !ok {
   121  				t.Errorf("no %s annotation found in the config map", constants.ComponentConfigHashAnnotationKey)
   122  			} else {
   123  				if signature != test.checksum {
   124  					t.Errorf("unexpected checksum - got %q, expected %q", signature, test.checksum)
   125  				}
   126  			}
   127  
   128  			// Verify that we have added an annotation (and not overwritten them)
   129  			expectedAnnotationCount := 1 + len(test.configMap.Annotations)
   130  			if len(target.Annotations) != expectedAnnotationCount {
   131  				t.Errorf("unexpected number of annotations - got %d, expected %d", len(target.Annotations), expectedAnnotationCount)
   132  			}
   133  		})
   134  	}
   135  }
   136  
   137  func TestVerifyConfigMapSignature(t *testing.T) {
   138  	tests := []struct {
   139  		desc      string
   140  		configMap *v1.ConfigMap
   141  		expectErr bool
   142  	}{
   143  		{
   144  			desc: "correct signature is acknowledged",
   145  			configMap: &v1.ConfigMap{
   146  				ObjectMeta: metav1.ObjectMeta{
   147  					Name:      "le-config",
   148  					Namespace: "le-namespace",
   149  					Labels: map[string]string{
   150  						"label1": "value1",
   151  						"label2": "value2",
   152  					},
   153  					Annotations: map[string]string{
   154  						"annotation1": "value1",
   155  						"annotation2": "value2",
   156  						constants.ComponentConfigHashAnnotationKey: "sha256:c8f8b724728a6d6684106e5e64e94ce811c9965d19dd44dd073cf86cf43bc238",
   157  					},
   158  				},
   159  				Data: map[string]string{
   160  					"foo": "bar",
   161  				},
   162  				BinaryData: map[string][]byte{
   163  					"bar": []byte("baz"),
   164  				},
   165  			},
   166  		},
   167  		{
   168  			desc: "wrong checksum leads to failure",
   169  			configMap: &v1.ConfigMap{
   170  				ObjectMeta: metav1.ObjectMeta{
   171  					Name:      "le-config",
   172  					Namespace: "le-namespace",
   173  					Labels: map[string]string{
   174  						"label1": "value1",
   175  						"label2": "value2",
   176  					},
   177  					Annotations: map[string]string{
   178  						"annotation1": "value1",
   179  						"annotation2": "value2",
   180  						constants.ComponentConfigHashAnnotationKey: "sha256:832cb34fc68fc370dd44dd91d5699c118ec49e46e5e6014866d6a827427b8f8c",
   181  					},
   182  				},
   183  				Data: map[string]string{
   184  					"foo": "bar",
   185  				},
   186  				BinaryData: map[string][]byte{
   187  					"bar": []byte("baz"),
   188  				},
   189  			},
   190  			expectErr: true,
   191  		},
   192  		{
   193  			desc: "missing signature means error",
   194  			configMap: &v1.ConfigMap{
   195  				ObjectMeta: metav1.ObjectMeta{
   196  					Name:      "le-config",
   197  					Namespace: "le-namespace",
   198  					Labels: map[string]string{
   199  						"label1": "value1",
   200  						"label2": "value2",
   201  					},
   202  					Annotations: map[string]string{
   203  						"annotation1": "value1",
   204  						"annotation2": "value2",
   205  					},
   206  				},
   207  				Data: map[string]string{
   208  					"foo": "bar",
   209  				},
   210  				BinaryData: map[string][]byte{
   211  					"bar": []byte("baz"),
   212  				},
   213  			},
   214  			expectErr: true,
   215  		},
   216  	}
   217  	for _, test := range tests {
   218  		t.Run(test.desc, func(t *testing.T) {
   219  			result := VerifyConfigMapSignature(test.configMap)
   220  			if result != !test.expectErr {
   221  				t.Errorf("unexpected result - got %t, expected %t", result, !test.expectErr)
   222  			}
   223  		})
   224  	}
   225  }
   226  

View as plain text