...

Source file src/k8s.io/kubectl/pkg/cmd/create/create_secret_test.go

Documentation: k8s.io/kubectl/pkg/cmd/create

     1  /*
     2  Copyright 2014 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 create
    18  
    19  import (
    20  	"os"
    21  	"testing"
    22  
    23  	"github.com/stretchr/testify/require"
    24  
    25  	corev1 "k8s.io/api/core/v1"
    26  	apiequality "k8s.io/apimachinery/pkg/api/equality"
    27  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    28  )
    29  
    30  func TestCreateSecretObject(t *testing.T) {
    31  	secretObject := newSecretObj("foo", "foo-namespace", corev1.SecretTypeDockerConfigJson)
    32  	expectedSecretObject := &corev1.Secret{
    33  		TypeMeta: metav1.TypeMeta{
    34  			APIVersion: corev1.SchemeGroupVersion.String(),
    35  			Kind:       "Secret",
    36  		},
    37  		ObjectMeta: metav1.ObjectMeta{
    38  			Name:      "foo",
    39  			Namespace: "foo-namespace",
    40  		},
    41  		Type: corev1.SecretTypeDockerConfigJson,
    42  		Data: map[string][]byte{},
    43  	}
    44  	t.Run("Creating a Secret Object", func(t *testing.T) {
    45  		if !apiequality.Semantic.DeepEqual(secretObject, expectedSecretObject) {
    46  			t.Errorf("expected:\n%#v\ngot:\n%#v", secretObject, expectedSecretObject)
    47  		}
    48  	})
    49  }
    50  
    51  func TestCreateSecretGeneric(t *testing.T) {
    52  	tests := map[string]struct {
    53  		secretName  string
    54  		secretType  string
    55  		fromLiteral []string
    56  		fromFile    []string
    57  		fromEnvFile []string
    58  		appendHash  bool
    59  		setup       func(t *testing.T, secretGenericOptions *CreateSecretOptions) func()
    60  
    61  		expected  *corev1.Secret
    62  		expectErr string
    63  	}{
    64  		"create_secret_foo": {
    65  			secretName: "foo",
    66  			expected: &corev1.Secret{
    67  				TypeMeta: metav1.TypeMeta{
    68  					APIVersion: corev1.SchemeGroupVersion.String(),
    69  					Kind:       "Secret",
    70  				},
    71  				ObjectMeta: metav1.ObjectMeta{
    72  					Name: "foo",
    73  				},
    74  				Data: map[string][]byte{},
    75  			},
    76  		},
    77  		"create_secret_foo_hash": {
    78  			secretName: "foo",
    79  			appendHash: true,
    80  			expected: &corev1.Secret{
    81  				TypeMeta: metav1.TypeMeta{
    82  					APIVersion: corev1.SchemeGroupVersion.String(),
    83  					Kind:       "Secret",
    84  				},
    85  				ObjectMeta: metav1.ObjectMeta{
    86  					Name: "foo-949tdgdkgg",
    87  				},
    88  				Data: map[string][]byte{},
    89  			},
    90  		},
    91  		"create_secret_foo_type": {
    92  			secretName: "foo",
    93  			secretType: "my-type",
    94  			expected: &corev1.Secret{
    95  				TypeMeta: metav1.TypeMeta{
    96  					APIVersion: corev1.SchemeGroupVersion.String(),
    97  					Kind:       "Secret",
    98  				},
    99  				ObjectMeta: metav1.ObjectMeta{
   100  					Name: "foo",
   101  				},
   102  				Data: map[string][]byte{},
   103  				Type: "my-type",
   104  			},
   105  		},
   106  		"create_secret_foo_type_hash": {
   107  			secretName: "foo",
   108  			secretType: "my-type",
   109  			appendHash: true,
   110  			expected: &corev1.Secret{
   111  				TypeMeta: metav1.TypeMeta{
   112  					APIVersion: corev1.SchemeGroupVersion.String(),
   113  					Kind:       "Secret",
   114  				},
   115  				ObjectMeta: metav1.ObjectMeta{
   116  					Name: "foo-dg474f9t76",
   117  				},
   118  				Data: map[string][]byte{},
   119  				Type: "my-type",
   120  			},
   121  		},
   122  		"create_secret_foo_two_literal": {
   123  			secretName:  "foo",
   124  			fromLiteral: []string{"key1=value1", "key2=value2"},
   125  			expected: &corev1.Secret{
   126  				TypeMeta: metav1.TypeMeta{
   127  					APIVersion: corev1.SchemeGroupVersion.String(),
   128  					Kind:       "Secret",
   129  				},
   130  				ObjectMeta: metav1.ObjectMeta{
   131  					Name: "foo",
   132  				},
   133  				Data: map[string][]byte{
   134  					"key1": []byte("value1"),
   135  					"key2": []byte("value2"),
   136  				},
   137  			},
   138  		},
   139  		"create_secret_foo_two_literal_hash": {
   140  			secretName:  "foo",
   141  			fromLiteral: []string{"key1=value1", "key2=value2"},
   142  			appendHash:  true,
   143  			expected: &corev1.Secret{
   144  				TypeMeta: metav1.TypeMeta{
   145  					APIVersion: corev1.SchemeGroupVersion.String(),
   146  					Kind:       "Secret",
   147  				},
   148  				ObjectMeta: metav1.ObjectMeta{
   149  					Name: "foo-tf72c228m4",
   150  				},
   151  				Data: map[string][]byte{
   152  					"key1": []byte("value1"),
   153  					"key2": []byte("value2"),
   154  				},
   155  			},
   156  		},
   157  		"create_secret_foo_key1_=value1": {
   158  			secretName:  "foo",
   159  			fromLiteral: []string{"key1==value1"},
   160  			expected: &corev1.Secret{
   161  				TypeMeta: metav1.TypeMeta{
   162  					APIVersion: corev1.SchemeGroupVersion.String(),
   163  					Kind:       "Secret",
   164  				},
   165  				ObjectMeta: metav1.ObjectMeta{
   166  					Name: "foo",
   167  				},
   168  				Data: map[string][]byte{
   169  					"key1": []byte("=value1"),
   170  				},
   171  			},
   172  		},
   173  		"create_secret_foo_key1_=value1_hash": {
   174  			secretName:  "foo",
   175  			fromLiteral: []string{"key1==value1"},
   176  			appendHash:  true,
   177  			expected: &corev1.Secret{
   178  				TypeMeta: metav1.TypeMeta{
   179  					APIVersion: corev1.SchemeGroupVersion.String(),
   180  					Kind:       "Secret",
   181  				},
   182  				ObjectMeta: metav1.ObjectMeta{
   183  					Name: "foo-fdcc8tkhh5",
   184  				},
   185  				Data: map[string][]byte{
   186  					"key1": []byte("=value1"),
   187  				},
   188  			},
   189  		},
   190  		"create_secret_foo_from_file_foo1_foo2_secret": {
   191  			secretName: "foo",
   192  			setup:      setupSecretBinaryFile([]byte{0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64}),
   193  			fromFile:   []string{"foo1", "foo2"},
   194  			expected: &corev1.Secret{
   195  				TypeMeta: metav1.TypeMeta{
   196  					APIVersion: corev1.SchemeGroupVersion.String(),
   197  					Kind:       "Secret",
   198  				},
   199  				ObjectMeta: metav1.ObjectMeta{
   200  					Name: "foo",
   201  				},
   202  				Data: map[string][]byte{
   203  					"foo1": []byte("hello world"),
   204  					"foo2": []byte("hello world"),
   205  				},
   206  			},
   207  		},
   208  		"create_secret_foo_from_file_foo1_foo2_hash": {
   209  			secretName: "foo",
   210  			setup:      setupSecretBinaryFile([]byte{0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64}),
   211  			fromFile:   []string{"foo1", "foo2"},
   212  			appendHash: true,
   213  			expected: &corev1.Secret{
   214  				TypeMeta: metav1.TypeMeta{
   215  					APIVersion: corev1.SchemeGroupVersion.String(),
   216  					Kind:       "Secret",
   217  				},
   218  				ObjectMeta: metav1.ObjectMeta{
   219  					Name: "foo-hbkh2cdb57",
   220  				},
   221  				Data: map[string][]byte{
   222  					"foo1": []byte("hello world"),
   223  					"foo2": []byte("hello world"),
   224  				},
   225  			},
   226  		},
   227  		"create_secret_foo_from_file_foo1_foo2_and": {
   228  			secretName: "foo",
   229  			setup:      setupSecretBinaryFile([]byte{0xff, 0xfd}),
   230  			fromFile:   []string{"foo1", "foo2"},
   231  			expected: &corev1.Secret{
   232  				TypeMeta: metav1.TypeMeta{
   233  					APIVersion: corev1.SchemeGroupVersion.String(),
   234  					Kind:       "Secret",
   235  				},
   236  				ObjectMeta: metav1.ObjectMeta{
   237  					Name: "foo",
   238  				},
   239  				Data: map[string][]byte{
   240  					"foo1": {0xff, 0xfd},
   241  					"foo2": {0xff, 0xfd},
   242  				},
   243  			},
   244  		},
   245  		"create_secret_foo_from_file_foo1_foo2_and_hash": {
   246  			secretName: "foo",
   247  			setup:      setupSecretBinaryFile([]byte{0xff, 0xfd}),
   248  			fromFile:   []string{"foo1", "foo2"},
   249  			appendHash: true,
   250  			expected: &corev1.Secret{
   251  				TypeMeta: metav1.TypeMeta{
   252  					APIVersion: corev1.SchemeGroupVersion.String(),
   253  					Kind:       "Secret",
   254  				},
   255  				ObjectMeta: metav1.ObjectMeta{
   256  					Name: "foo-mkhg4ktk4d",
   257  				},
   258  				Data: map[string][]byte{
   259  					"foo1": {0xff, 0xfd},
   260  					"foo2": {0xff, 0xfd},
   261  				},
   262  			},
   263  		},
   264  		"create_secret_valid_env_from_env_file": {
   265  			secretName:  "valid_env",
   266  			setup:       setupSecretEnvFile([][]string{{"key1=value1", "#", "", "key2=value2"}}),
   267  			fromEnvFile: []string{"file.env"},
   268  			expected: &corev1.Secret{
   269  				TypeMeta: metav1.TypeMeta{
   270  					APIVersion: corev1.SchemeGroupVersion.String(),
   271  					Kind:       "Secret",
   272  				},
   273  				ObjectMeta: metav1.ObjectMeta{
   274  					Name: "valid_env",
   275  				},
   276  				Data: map[string][]byte{
   277  					"key1": []byte("value1"),
   278  					"key2": []byte("value2"),
   279  				},
   280  			},
   281  		},
   282  		"create_secret_valid_env_from_env_file_hash": {
   283  			secretName:  "valid_env",
   284  			setup:       setupSecretEnvFile([][]string{{"key1=value1", "#", "", "key2=value2"}}),
   285  			fromEnvFile: []string{"file.env"},
   286  			appendHash:  true,
   287  			expected: &corev1.Secret{
   288  				TypeMeta: metav1.TypeMeta{
   289  					APIVersion: corev1.SchemeGroupVersion.String(),
   290  					Kind:       "Secret",
   291  				},
   292  				ObjectMeta: metav1.ObjectMeta{
   293  					Name: "valid_env-bkb2m2965h",
   294  				},
   295  				Data: map[string][]byte{
   296  					"key1": []byte("value1"),
   297  					"key2": []byte("value2"),
   298  				},
   299  			},
   300  		},
   301  		"create_two_secret_valid_env_from_env_file": {
   302  			secretName:  "two_valid_env",
   303  			setup:       setupSecretEnvFile([][]string{{"key1=value1", "#", "", "key2=value2"}, {"key3=value3"}}),
   304  			fromEnvFile: []string{"file1.env", "file2.env"},
   305  			expected: &corev1.Secret{
   306  				TypeMeta: metav1.TypeMeta{
   307  					APIVersion: corev1.SchemeGroupVersion.String(),
   308  					Kind:       "Secret",
   309  				},
   310  				ObjectMeta: metav1.ObjectMeta{
   311  					Name: "two_valid_env",
   312  				},
   313  				Data: map[string][]byte{
   314  					"key1": []byte("value1"),
   315  					"key2": []byte("value2"),
   316  					"key3": []byte("value3"),
   317  				},
   318  			},
   319  		},
   320  		"create_two_secret_valid_env_from_env_file_hash": {
   321  			secretName:  "two_valid_env",
   322  			setup:       setupSecretEnvFile([][]string{{"key1=value1", "#", "", "key2=value2"}, {"key3=value3"}}),
   323  			fromEnvFile: []string{"file1.env", "file2.env"},
   324  			appendHash:  true,
   325  			expected: &corev1.Secret{
   326  				TypeMeta: metav1.TypeMeta{
   327  					APIVersion: corev1.SchemeGroupVersion.String(),
   328  					Kind:       "Secret",
   329  				},
   330  				ObjectMeta: metav1.ObjectMeta{
   331  					Name: "two_valid_env-gd56gct5cf",
   332  				},
   333  				Data: map[string][]byte{
   334  					"key1": []byte("value1"),
   335  					"key2": []byte("value2"),
   336  					"key3": []byte("value3"),
   337  				},
   338  			},
   339  		},
   340  		"create_secret_get_env_from_env_file": {
   341  			secretName: "get_env",
   342  			setup: func() func(t *testing.T, secretGenericOptions *CreateSecretOptions) func() {
   343  				t.Setenv("g_key1", "1")
   344  				t.Setenv("g_key2", "2")
   345  				return setupSecretEnvFile([][]string{{"g_key1", "g_key2="}})
   346  			}(),
   347  			fromEnvFile: []string{"file.env"},
   348  			expected: &corev1.Secret{
   349  				TypeMeta: metav1.TypeMeta{
   350  					APIVersion: corev1.SchemeGroupVersion.String(),
   351  					Kind:       "Secret",
   352  				},
   353  				ObjectMeta: metav1.ObjectMeta{
   354  					Name: "get_env",
   355  				},
   356  				Data: map[string][]byte{
   357  					"g_key1": []byte("1"),
   358  					"g_key2": []byte(""),
   359  				},
   360  			},
   361  		},
   362  		"create_secret_get_env_from_env_file_hash": {
   363  			secretName: "get_env",
   364  			setup: func() func(t *testing.T, secretGenericOptions *CreateSecretOptions) func() {
   365  				t.Setenv("g_key1", "1")
   366  				t.Setenv("g_key2", "2")
   367  				return setupSecretEnvFile([][]string{{"g_key1", "g_key2="}})
   368  			}(),
   369  			fromEnvFile: []string{"file.env"},
   370  			appendHash:  true,
   371  			expected: &corev1.Secret{
   372  				TypeMeta: metav1.TypeMeta{
   373  					APIVersion: corev1.SchemeGroupVersion.String(),
   374  					Kind:       "Secret",
   375  				},
   376  				ObjectMeta: metav1.ObjectMeta{
   377  					Name: "get_env-68mt8f2kkt",
   378  				},
   379  				Data: map[string][]byte{
   380  					"g_key1": []byte("1"),
   381  					"g_key2": []byte(""),
   382  				},
   383  			},
   384  		},
   385  		"create_secret_value_with_space_from_env_file": {
   386  			secretName:  "value_with_space",
   387  			setup:       setupSecretEnvFile([][]string{{"   key1=  value1"}}),
   388  			fromEnvFile: []string{"file.env"},
   389  			expected: &corev1.Secret{
   390  				TypeMeta: metav1.TypeMeta{
   391  					APIVersion: corev1.SchemeGroupVersion.String(),
   392  					Kind:       "Secret",
   393  				},
   394  				ObjectMeta: metav1.ObjectMeta{
   395  					Name: "value_with_space",
   396  				},
   397  				Data: map[string][]byte{
   398  					"key1": []byte("  value1"),
   399  				},
   400  			},
   401  		},
   402  		"create_secret_value_with_space_from_env_file_hash": {
   403  			secretName:  "valid_with_space",
   404  			setup:       setupSecretEnvFile([][]string{{"   key1=  value1"}}),
   405  			fromEnvFile: []string{"file.env"},
   406  			appendHash:  true,
   407  			expected: &corev1.Secret{
   408  				TypeMeta: metav1.TypeMeta{
   409  					APIVersion: corev1.SchemeGroupVersion.String(),
   410  					Kind:       "Secret",
   411  				},
   412  				ObjectMeta: metav1.ObjectMeta{
   413  					Name: "valid_with_space-bhkb4gfck6",
   414  				},
   415  				Data: map[string][]byte{
   416  					"key1": []byte("  value1"),
   417  				},
   418  			},
   419  		},
   420  		"create_invalid_secret_filepath_contains_=": {
   421  			secretName: "foo",
   422  			fromFile:   []string{"key1=/file=2"},
   423  			expectErr:  `key names or file paths cannot contain '='`,
   424  		},
   425  		"create_invalid_secret_filepath_key_contains_=": {
   426  			secretName: "foo",
   427  			fromFile:   []string{"=key=/file1"},
   428  			expectErr:  `key names or file paths cannot contain '='`,
   429  		},
   430  		"create_invalid_secret_literal_key_contains_=": {
   431  			secretName:  "foo",
   432  			fromLiteral: []string{"=key=value1"},
   433  			expectErr:   `invalid literal source =key=value1, expected key=value`,
   434  		},
   435  		"create_invalid_secret_literal_key_with_invalid_character": {
   436  			secretName:  "foo",
   437  			fromLiteral: []string{"key#1=value1"},
   438  			expectErr:   `"key#1" is not valid key name for a Secret a valid config key must consist of alphanumeric characters, '-', '_' or '.' (e.g. 'key.name',  or 'KEY_NAME',  or 'key-name', regex used for validation is '[-._a-zA-Z0-9]+')`,
   439  		},
   440  		"create_invalid_secret_env_key_contains_#": {
   441  			secretName:  "invalid_key",
   442  			setup:       setupSecretEnvFile([][]string{{"key#1=value1"}}),
   443  			fromEnvFile: []string{"file.env"},
   444  			expectErr:   `"key#1" is not a valid key name: a valid environment variable name must consist of alphabetic characters, digits, '_', '-', or '.', and must not start with a digit (e.g. 'my.env-name',  or 'MY_ENV.NAME',  or 'MyEnvName1', regex used for validation is '[-._a-zA-Z][-._a-zA-Z0-9]*')`,
   445  		},
   446  		"create_invalid_secret_env_key_start_with_digit": {
   447  			secretName:  "invalid_key",
   448  			setup:       setupSecretEnvFile([][]string{{"1key=value1"}}),
   449  			fromEnvFile: []string{"file.env"},
   450  			expectErr:   `"1key" is not a valid key name: a valid environment variable name must consist of alphabetic characters, digits, '_', '-', or '.', and must not start with a digit (e.g. 'my.env-name',  or 'MY_ENV.NAME',  or 'MyEnvName1', regex used for validation is '[-._a-zA-Z][-._a-zA-Z0-9]*')`,
   451  		},
   452  		"create_invalid_secret_env_key_with_invalid_character": {
   453  			secretName:  "invalid_key",
   454  			setup:       setupSecretEnvFile([][]string{{"key@=value1"}}),
   455  			fromEnvFile: []string{"file.env"},
   456  			expectErr:   `"key@" is not a valid key name: a valid environment variable name must consist of alphabetic characters, digits, '_', '-', or '.', and must not start with a digit (e.g. 'my.env-name',  or 'MY_ENV.NAME',  or 'MyEnvName1', regex used for validation is '[-._a-zA-Z][-._a-zA-Z0-9]*')`,
   457  		},
   458  		"create_invalid_secret_duplicate_key1": {
   459  			secretName:  "foo",
   460  			fromLiteral: []string{"key1=value1", "key1=value2"},
   461  			expectErr:   `cannot add key key1, another key by that name already exists`,
   462  		},
   463  		"create_invalid_secret_no_file": {
   464  			secretName: "foo",
   465  			fromFile:   []string{"key1=/file1"},
   466  			expectErr:  `error reading /file1: no such file or directory`,
   467  		},
   468  		"create_invalid_secret_invalid_literal": {
   469  			secretName:  "foo",
   470  			fromLiteral: []string{"key1value1"},
   471  			expectErr:   `invalid literal source key1value1, expected key=value`,
   472  		},
   473  		"create_invalid_secret_invalid_filepath": {
   474  			secretName: "foo",
   475  			fromFile:   []string{"key1==file1"},
   476  			expectErr:  `key names or file paths cannot contain '='`,
   477  		},
   478  		"create_invalid_secret_no_name": {
   479  			expectErr: `name must be specified`,
   480  		},
   481  		"create_invalid_secret_too_many_args": {
   482  			secretName:  "too_many_args",
   483  			fromFile:    []string{"key1=/file1"},
   484  			fromEnvFile: []string{"foo"},
   485  			expectErr:   `from-env-file cannot be combined with from-file or from-literal`,
   486  		},
   487  		"create_invalid_secret_too_many_args_1": {
   488  			secretName:  "too_many_args_1",
   489  			fromLiteral: []string{"key1=value1"},
   490  			fromEnvFile: []string{"foo"},
   491  			expectErr:   `from-env-file cannot be combined with from-file or from-literal`,
   492  		},
   493  		"create_invalid_secret_too_many_args_2": {
   494  			secretName:  "too_many_args_2",
   495  			fromFile:    []string{"key1=/file1"},
   496  			fromLiteral: []string{"key1=value1"},
   497  			fromEnvFile: []string{"foo"},
   498  			expectErr:   `from-env-file cannot be combined with from-file or from-literal`,
   499  		},
   500  	}
   501  
   502  	// run all the tests
   503  	for name, test := range tests {
   504  		t.Run(name, func(t *testing.T) {
   505  			var secret *corev1.Secret = nil
   506  			secretOptions := CreateSecretOptions{
   507  				Name:           test.secretName,
   508  				Type:           test.secretType,
   509  				AppendHash:     test.appendHash,
   510  				FileSources:    test.fromFile,
   511  				LiteralSources: test.fromLiteral,
   512  				EnvFileSources: test.fromEnvFile,
   513  			}
   514  			if test.setup != nil {
   515  				if teardown := test.setup(t, &secretOptions); teardown != nil {
   516  					defer teardown()
   517  				}
   518  			}
   519  			err := secretOptions.Validate()
   520  			if err == nil {
   521  				secret, err = secretOptions.createSecret()
   522  			}
   523  
   524  			if test.expectErr == "" {
   525  				require.NoError(t, err)
   526  				if !apiequality.Semantic.DeepEqual(secret, test.expected) {
   527  					t.Errorf("\nexpected:\n%#v\ngot:\n%#v", test.expected, secret)
   528  				}
   529  			} else {
   530  				require.Error(t, err)
   531  				require.EqualError(t, err, test.expectErr)
   532  			}
   533  		})
   534  	}
   535  }
   536  
   537  func setupSecretEnvFile(lines [][]string) func(*testing.T, *CreateSecretOptions) func() {
   538  	return func(t *testing.T, secretOptions *CreateSecretOptions) func() {
   539  		files := []*os.File{}
   540  		filenames := secretOptions.EnvFileSources
   541  		for _, filename := range filenames {
   542  			file, err := os.CreateTemp("", filename)
   543  			if err != nil {
   544  				t.Errorf("unexpected error: %v", err)
   545  			}
   546  			files = append(files, file)
   547  		}
   548  		for i, f := range files {
   549  			for _, l := range lines[i] {
   550  				f.WriteString(l)
   551  				f.WriteString("\r\n")
   552  			}
   553  			f.Close()
   554  			secretOptions.EnvFileSources[i] = f.Name()
   555  		}
   556  		return func() {
   557  			for _, f := range files {
   558  				os.Remove(f.Name())
   559  			}
   560  		}
   561  	}
   562  }
   563  
   564  func setupSecretBinaryFile(data []byte) func(*testing.T, *CreateSecretOptions) func() {
   565  	return func(t *testing.T, secretOptions *CreateSecretOptions) func() {
   566  		tmp, _ := os.MkdirTemp("", "")
   567  		files := secretOptions.FileSources
   568  		for i, file := range files {
   569  			f := tmp + "/" + file
   570  			os.WriteFile(f, data, 0644)
   571  			secretOptions.FileSources[i] = f
   572  		}
   573  		return func() {
   574  			for _, file := range files {
   575  				f := tmp + "/" + file
   576  				os.RemoveAll(f)
   577  			}
   578  		}
   579  	}
   580  }
   581  

View as plain text