mirror of
				https://github.com/optim-enterprises-bv/vault.git
				synced 2025-10-31 02:28:09 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			325 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			325 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright (c) HashiCorp, Inc.
 | |
| // SPDX-License-Identifier: MPL-2.0
 | |
| 
 | |
| package api
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"net/http"
 | |
| 	"net/http/httptest"
 | |
| 	"reflect"
 | |
| 	"testing"
 | |
| 
 | |
| 	"github.com/hashicorp/go-secure-stdlib/strutil"
 | |
| )
 | |
| 
 | |
| func TestRegisterPlugin(t *testing.T) {
 | |
| 	mockVaultServer := httptest.NewServer(http.HandlerFunc(mockVaultHandlerRegister))
 | |
| 	defer mockVaultServer.Close()
 | |
| 
 | |
| 	cfg := DefaultConfig()
 | |
| 	cfg.Address = mockVaultServer.URL
 | |
| 	client, err := NewClient(cfg)
 | |
| 	if err != nil {
 | |
| 		t.Fatal(err)
 | |
| 	}
 | |
| 
 | |
| 	err = client.Sys().RegisterPluginWithContext(context.Background(), &RegisterPluginInput{
 | |
| 		Version: "v1.0.0",
 | |
| 	})
 | |
| 	if err != nil {
 | |
| 		t.Fatal(err)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func TestListPlugins(t *testing.T) {
 | |
| 	mockVaultServer := httptest.NewServer(http.HandlerFunc(mockVaultHandlerList))
 | |
| 	defer mockVaultServer.Close()
 | |
| 
 | |
| 	cfg := DefaultConfig()
 | |
| 	cfg.Address = mockVaultServer.URL
 | |
| 	client, err := NewClient(cfg)
 | |
| 	if err != nil {
 | |
| 		t.Fatal(err)
 | |
| 	}
 | |
| 
 | |
| 	for name, tc := range map[string]struct {
 | |
| 		input           ListPluginsInput
 | |
| 		expectedPlugins map[PluginType][]string
 | |
| 	}{
 | |
| 		"no type specified": {
 | |
| 			input: ListPluginsInput{},
 | |
| 			expectedPlugins: map[PluginType][]string{
 | |
| 				PluginTypeCredential: {"alicloud"},
 | |
| 				PluginTypeDatabase:   {"cassandra-database-plugin"},
 | |
| 				PluginTypeSecrets:    {"ad", "alicloud"},
 | |
| 			},
 | |
| 		},
 | |
| 		"only auth plugins": {
 | |
| 			input: ListPluginsInput{Type: PluginTypeCredential},
 | |
| 			expectedPlugins: map[PluginType][]string{
 | |
| 				PluginTypeCredential: {"alicloud"},
 | |
| 			},
 | |
| 		},
 | |
| 		"only database plugins": {
 | |
| 			input: ListPluginsInput{Type: PluginTypeDatabase},
 | |
| 			expectedPlugins: map[PluginType][]string{
 | |
| 				PluginTypeDatabase: {"cassandra-database-plugin"},
 | |
| 			},
 | |
| 		},
 | |
| 		"only secret plugins": {
 | |
| 			input: ListPluginsInput{Type: PluginTypeSecrets},
 | |
| 			expectedPlugins: map[PluginType][]string{
 | |
| 				PluginTypeSecrets: {"ad", "alicloud"},
 | |
| 			},
 | |
| 		},
 | |
| 	} {
 | |
| 		t.Run(name, func(t *testing.T) {
 | |
| 			resp, err := client.Sys().ListPluginsWithContext(context.Background(), &tc.input)
 | |
| 			if err != nil {
 | |
| 				t.Fatal(err)
 | |
| 			}
 | |
| 
 | |
| 			for pluginType, expected := range tc.expectedPlugins {
 | |
| 				actualPlugins := resp.PluginsByType[pluginType]
 | |
| 				if len(expected) != len(actualPlugins) {
 | |
| 					t.Fatal("Wrong number of plugins", expected, actualPlugins)
 | |
| 				}
 | |
| 				for i := range actualPlugins {
 | |
| 					if expected[i] != actualPlugins[i] {
 | |
| 						t.Fatalf("Expected %q but got %q", expected[i], actualPlugins[i])
 | |
| 					}
 | |
| 				}
 | |
| 
 | |
| 				for _, expectedPlugin := range expected {
 | |
| 					found := false
 | |
| 					for _, plugin := range resp.Details {
 | |
| 						if plugin.Type == pluginType.String() && plugin.Name == expectedPlugin {
 | |
| 							found = true
 | |
| 							break
 | |
| 						}
 | |
| 					}
 | |
| 					if !found {
 | |
| 						t.Errorf("Expected to find %s plugin %s but not found in details: %#v", pluginType.String(), expectedPlugin, resp.Details)
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
| 			for _, actual := range resp.Details {
 | |
| 				pluginType, err := ParsePluginType(actual.Type)
 | |
| 				if err != nil {
 | |
| 					t.Fatal(err)
 | |
| 				}
 | |
| 				if !strutil.StrListContains(tc.expectedPlugins[pluginType], actual.Name) {
 | |
| 					t.Errorf("Did not expect to find %s in details", actual.Name)
 | |
| 				}
 | |
| 			}
 | |
| 		})
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func TestGetPlugin(t *testing.T) {
 | |
| 	for name, tc := range map[string]struct {
 | |
| 		version  string
 | |
| 		body     string
 | |
| 		expected GetPluginResponse
 | |
| 	}{
 | |
| 		"builtin": {
 | |
| 			body: getResponse,
 | |
| 			expected: GetPluginResponse{
 | |
| 				Args:              nil,
 | |
| 				Builtin:           true,
 | |
| 				Command:           "",
 | |
| 				Name:              "azure",
 | |
| 				SHA256:            "",
 | |
| 				DeprecationStatus: "supported",
 | |
| 				Version:           "v0.14.0+builtin",
 | |
| 			},
 | |
| 		},
 | |
| 		"external": {
 | |
| 			version: "v1.0.0",
 | |
| 			body:    getResponseExternal,
 | |
| 			expected: GetPluginResponse{
 | |
| 				Args:              []string{},
 | |
| 				Builtin:           false,
 | |
| 				Command:           "azure-plugin",
 | |
| 				Name:              "azure",
 | |
| 				SHA256:            "8ba442dba253803685b05e35ad29dcdebc48dec16774614aa7a4ebe53c1e90e1",
 | |
| 				DeprecationStatus: "",
 | |
| 				Version:           "v1.0.0",
 | |
| 			},
 | |
| 		},
 | |
| 		"old server": {
 | |
| 			body: getResponseOldServerVersion,
 | |
| 			expected: GetPluginResponse{
 | |
| 				Args:              nil,
 | |
| 				Builtin:           true,
 | |
| 				Command:           "",
 | |
| 				Name:              "azure",
 | |
| 				SHA256:            "",
 | |
| 				DeprecationStatus: "",
 | |
| 				Version:           "",
 | |
| 			},
 | |
| 		},
 | |
| 	} {
 | |
| 		t.Run(name, func(t *testing.T) {
 | |
| 			mockVaultServer := httptest.NewServer(http.HandlerFunc(mockVaultHandlerInfo(tc.body)))
 | |
| 			defer mockVaultServer.Close()
 | |
| 
 | |
| 			cfg := DefaultConfig()
 | |
| 			cfg.Address = mockVaultServer.URL
 | |
| 			client, err := NewClient(cfg)
 | |
| 			if err != nil {
 | |
| 				t.Fatal(err)
 | |
| 			}
 | |
| 
 | |
| 			input := GetPluginInput{
 | |
| 				Name: "azure",
 | |
| 				Type: PluginTypeSecrets,
 | |
| 			}
 | |
| 			if tc.version != "" {
 | |
| 				input.Version = tc.version
 | |
| 			}
 | |
| 
 | |
| 			info, err := client.Sys().GetPluginWithContext(context.Background(), &input)
 | |
| 			if err != nil {
 | |
| 				t.Fatal(err)
 | |
| 			}
 | |
| 
 | |
| 			if !reflect.DeepEqual(tc.expected, *info) {
 | |
| 				t.Errorf("expected: %#v\ngot: %#v", tc.expected, info)
 | |
| 			}
 | |
| 		})
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func mockVaultHandlerInfo(body string) func(w http.ResponseWriter, _ *http.Request) {
 | |
| 	return func(w http.ResponseWriter, _ *http.Request) {
 | |
| 		_, _ = w.Write([]byte(body))
 | |
| 	}
 | |
| }
 | |
| 
 | |
| const getResponse = `{
 | |
|     "request_id": "e93d3f93-8e4f-8443-a803-f1c97c495241",
 | |
|     "lease_id": "",
 | |
|     "renewable": false,
 | |
|     "lease_duration": 0,
 | |
|     "data": {
 | |
|         "args": null,
 | |
|         "builtin": true,
 | |
|         "command": "",
 | |
|         "deprecation_status": "supported",
 | |
|         "name": "azure",
 | |
|         "sha256": "",
 | |
|         "version": "v0.14.0+builtin"
 | |
|     },
 | |
|     "wrap_info": null,
 | |
|     "warnings": null,
 | |
|     "auth": null
 | |
| }`
 | |
| 
 | |
| const getResponseExternal = `{
 | |
|     "request_id": "e93d3f93-8e4f-8443-a803-f1c97c495241",
 | |
|     "lease_id": "",
 | |
|     "renewable": false,
 | |
|     "lease_duration": 0,
 | |
|     "data": {
 | |
|         "args": [],
 | |
|         "builtin": false,
 | |
|         "command": "azure-plugin",
 | |
|         "name": "azure",
 | |
|         "sha256": "8ba442dba253803685b05e35ad29dcdebc48dec16774614aa7a4ebe53c1e90e1",
 | |
|         "version": "v1.0.0"
 | |
|     },
 | |
|     "wrap_info": null,
 | |
|     "warnings": null,
 | |
|     "auth": null
 | |
| }`
 | |
| 
 | |
| const getResponseOldServerVersion = `{
 | |
|     "request_id": "e93d3f93-8e4f-8443-a803-f1c97c495241",
 | |
|     "lease_id": "",
 | |
|     "renewable": false,
 | |
|     "lease_duration": 0,
 | |
|     "data": {
 | |
|         "args": null,
 | |
|         "builtin": true,
 | |
|         "command": "",
 | |
|         "name": "azure",
 | |
|         "sha256": ""
 | |
|     },
 | |
|     "wrap_info": null,
 | |
|     "warnings": null,
 | |
|     "auth": null
 | |
| }`
 | |
| 
 | |
| func mockVaultHandlerList(w http.ResponseWriter, _ *http.Request) {
 | |
| 	_, _ = w.Write([]byte(listUntypedResponse))
 | |
| }
 | |
| 
 | |
| const listUntypedResponse = `{
 | |
|   "request_id": "82601a91-cd7a-718f-feca-f573449cc1bb",
 | |
|   "lease_id": "",
 | |
|   "renewable": false,
 | |
|   "lease_duration": 0,
 | |
|   "data": {
 | |
|     "auth": [
 | |
|       "alicloud"
 | |
|     ],
 | |
|     "database": [
 | |
|       "cassandra-database-plugin"
 | |
|     ],
 | |
|     "secret": [
 | |
|       "ad",
 | |
|       "alicloud"
 | |
|     ],
 | |
|     "some_other_unexpected_key": [
 | |
|       {
 | |
|         "objectKey": "objectValue"
 | |
|       },
 | |
|       {
 | |
|         "arbitraryData": 7
 | |
|       }
 | |
|     ],
 | |
|     "detailed": [
 | |
|       {
 | |
|         "type": "auth",
 | |
|         "name": "alicloud",
 | |
|         "version": "v0.13.0+builtin",
 | |
|         "builtin": true,
 | |
|         "deprecation_status": "supported"
 | |
|       },
 | |
|       {
 | |
|         "type": "database",
 | |
|         "name": "cassandra-database-plugin",
 | |
|         "version": "v1.13.0+builtin.vault",
 | |
|         "builtin": true,
 | |
|         "deprecation_status": "supported"
 | |
|       },
 | |
|       {
 | |
|         "type": "secret",
 | |
|         "name": "ad",
 | |
|         "version": "v0.14.0+builtin",
 | |
|         "builtin": true,
 | |
|         "deprecation_status": "supported"
 | |
|       },
 | |
|       {
 | |
|         "type": "secret",
 | |
|         "name": "alicloud",
 | |
|         "version": "v0.13.0+builtin",
 | |
|         "builtin": true,
 | |
|         "deprecation_status": "supported"
 | |
|       }
 | |
|     ]
 | |
|   },
 | |
|   "wrap_info": null,
 | |
|   "warnings": null,
 | |
|   "auth": null
 | |
| }`
 | |
| 
 | |
| func mockVaultHandlerRegister(w http.ResponseWriter, _ *http.Request) {
 | |
| 	_, _ = w.Write([]byte(registerResponse))
 | |
| }
 | |
| 
 | |
| const registerResponse = `{}`
 | 
