mirror of
				https://github.com/optim-enterprises-bv/vault.git
				synced 2025-10-31 02:28:09 +00:00 
			
		
		
		
	VAULT-33758: IPv6 address conformance for proxy and agent (#29517)
This is a follow-up to our initial work[0] to address RFC-5952 §4 conformance for IPv6 addresses in Vault. The initial pass focused on the vault server configuration and start-up routines. This follow-up focuses on Agent and Proxy, with a few minor improvements for server. The approach generally mirrors the server implementation but also adds support for normalization with CLI configuration overrides. One aspect we do not normalize currently is Agent/Proxy client creation to the Vault server with credentials taken from environment variables, as it would require larger changes to the `api` module. In practice this ought to be fine for the majority of cases. [0]: https://github.com/hashicorp/vault/pull/29228
This commit is contained in:
		| @@ -24,60 +24,64 @@ func getDefaultCliHeaders(t *testing.T) http.Header { | ||||
| } | ||||
|  | ||||
| func TestClient_FlagHeader(t *testing.T) { | ||||
| 	defaultHeaders := getDefaultCliHeaders(t) | ||||
| 	t.Parallel() | ||||
|  | ||||
| 	cases := []struct { | ||||
| 	cases := map[string]struct { | ||||
| 		Input map[string]string | ||||
| 		Valid bool | ||||
| 	}{ | ||||
| 		{ | ||||
| 		"empty": { | ||||
| 			map[string]string{}, | ||||
| 			true, | ||||
| 		}, | ||||
| 		{ | ||||
| 		"valid": { | ||||
| 			map[string]string{"foo": "bar", "header2": "value2"}, | ||||
| 			true, | ||||
| 		}, | ||||
| 		{ | ||||
| 		"invalid": { | ||||
| 			map[string]string{"X-Vault-foo": "bar", "header2": "value2"}, | ||||
| 			false, | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	for _, tc := range cases { | ||||
| 		expectedHeaders := defaultHeaders.Clone() | ||||
| 		for key, val := range tc.Input { | ||||
| 			expectedHeaders.Add(key, val) | ||||
| 		} | ||||
|  | ||||
| 		bc := &BaseCommand{flagHeader: tc.Input} | ||||
| 		cli, err := bc.Client() | ||||
|  | ||||
| 		if err == nil && !tc.Valid { | ||||
| 			t.Errorf("No error for input[%#v], but not valid", tc.Input) | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		if err != nil { | ||||
| 			if tc.Valid { | ||||
| 				t.Errorf("Error[%v] with input[%#v], but valid", err, tc.Input) | ||||
| 	for name, tc := range cases { | ||||
| 		t.Run(name, func(t *testing.T) { | ||||
| 			t.Parallel() | ||||
| 			expectedHeaders := getDefaultCliHeaders(t) | ||||
| 			for key, val := range tc.Input { | ||||
| 				expectedHeaders.Add(key, val) | ||||
| 			} | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		if cli == nil { | ||||
| 			t.Error("client should not be nil") | ||||
| 		} | ||||
| 			bc := &BaseCommand{flagHeader: tc.Input} | ||||
| 			cli, err := bc.Client() | ||||
|  | ||||
| 		actualHeaders := cli.Headers() | ||||
| 		if !reflect.DeepEqual(expectedHeaders, actualHeaders) { | ||||
| 			t.Errorf("expected [%#v] but got [%#v]", expectedHeaders, actualHeaders) | ||||
| 		} | ||||
| 			if err == nil && !tc.Valid { | ||||
| 				t.Errorf("No error for input[%#v], but not valid", tc.Input) | ||||
| 			} | ||||
|  | ||||
| 			if err != nil { | ||||
| 				if tc.Valid { | ||||
| 					t.Errorf("Error[%v] with input[%#v], but valid", err, tc.Input) | ||||
| 				} | ||||
| 				return | ||||
| 			} | ||||
|  | ||||
| 			if cli == nil { | ||||
| 				t.Error("client should not be nil") | ||||
| 			} | ||||
|  | ||||
| 			actualHeaders := cli.Headers() | ||||
| 			if !reflect.DeepEqual(expectedHeaders, actualHeaders) { | ||||
| 				t.Errorf("expected [%#v] but got [%#v]", expectedHeaders, actualHeaders) | ||||
| 			} | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // TestClient_HCPConfiguration tests that the HCP configuration is applied correctly when it exists in cache. | ||||
| func TestClient_HCPConfiguration(t *testing.T) { | ||||
| 	t.Parallel() | ||||
|  | ||||
| 	cases := map[string]struct { | ||||
| 		Valid        bool | ||||
| 		ExpectedAddr string | ||||
| @@ -94,7 +98,8 @@ func TestClient_HCPConfiguration(t *testing.T) { | ||||
|  | ||||
| 	for n, tst := range cases { | ||||
| 		t.Run(n, func(t *testing.T) { | ||||
| 			bc := &BaseCommand{hcpTokenHelper: &hcpvlib.TestingHCPTokenHelper{tst.Valid}} | ||||
| 			t.Parallel() | ||||
| 			bc := &BaseCommand{hcpTokenHelper: &hcpvlib.TestingHCPTokenHelper{ValidCache: tst.Valid}} | ||||
| 			cli, err := bc.Client() | ||||
| 			assert.NoError(t, err) | ||||
|  | ||||
| @@ -109,3 +114,80 @@ func TestClient_HCPConfiguration(t *testing.T) { | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Test_FlagSet_StringVar_Normalizers verifies that the normalizer callbacks | ||||
| // works as expected. | ||||
| func Test_FlagSet_StringVar_Normalizers(t *testing.T) { | ||||
| 	appendA := func(in string) string { return in + "a" } | ||||
| 	prependB := func(in string) string { return "b" + in } | ||||
|  | ||||
| 	for name, test := range map[string]struct { | ||||
| 		in            func() *StringVar | ||||
| 		envVars       map[string]string | ||||
| 		expectedValue string | ||||
| 	}{ | ||||
| 		"no normalizers no env vars uses default value": { | ||||
| 			in: func() *StringVar { | ||||
| 				resT := "" | ||||
| 				return &StringVar{ | ||||
| 					Name:    "test", | ||||
| 					Target:  &resT, | ||||
| 					EnvVar:  "VAULT_TEST", | ||||
| 					Default: "default", | ||||
| 				} | ||||
| 			}, | ||||
| 			expectedValue: "default", | ||||
| 		}, | ||||
| 		"one normalizer no env vars normalizes default value": { | ||||
| 			in: func() *StringVar { | ||||
| 				resT := "" | ||||
| 				return &StringVar{ | ||||
| 					Name:        "test", | ||||
| 					Target:      &resT, | ||||
| 					EnvVar:      "VAULT_TEST", | ||||
| 					Default:     "default", | ||||
| 					Normalizers: []func(string) string{appendA}, | ||||
| 				} | ||||
| 			}, | ||||
| 			expectedValue: "defaulta", | ||||
| 		}, | ||||
| 		"two normalizers no env vars normalizes default value with both": { | ||||
| 			in: func() *StringVar { | ||||
| 				resT := "" | ||||
| 				return &StringVar{ | ||||
| 					Name:        "test", | ||||
| 					Target:      &resT, | ||||
| 					EnvVar:      "VAULT_TEST", | ||||
| 					Default:     "default", | ||||
| 					Normalizers: []func(string) string{appendA, prependB}, | ||||
| 				} | ||||
| 			}, | ||||
| 			expectedValue: "bdefaulta", | ||||
| 		}, | ||||
| 		"two normalizers with env vars normalizes env var value with both": { | ||||
| 			in: func() *StringVar { | ||||
| 				resT := "" | ||||
| 				return &StringVar{ | ||||
| 					Name:        "test", | ||||
| 					Target:      &resT, | ||||
| 					EnvVar:      "VAULT_TEST", | ||||
| 					Default:     "default", | ||||
| 					Normalizers: []func(string) string{appendA, prependB}, | ||||
| 				} | ||||
| 			}, | ||||
| 			envVars:       map[string]string{"VAULT_TEST": "env_override"}, | ||||
| 			expectedValue: "benv_overridea", | ||||
| 		}, | ||||
| 	} { | ||||
| 		t.Run(name, func(t *testing.T) { | ||||
| 			for k, v := range test.envVars { | ||||
| 				t.Setenv(k, v) | ||||
| 			} | ||||
| 			fsets := NewFlagSets(nil) | ||||
| 			fs := fsets.NewFlagSet("test") | ||||
| 			sv := test.in() | ||||
| 			fs.StringVar(sv) | ||||
| 			require.Equal(t, test.expectedValue, *sv.Target) | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Ryan Cragun
					Ryan Cragun