google.golang.org/grpc@v1.72.2/internal/testutils/xds/e2e/bootstrap.go (about) 1 /* 2 * 3 * Copyright 2020 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 package e2e 20 21 import ( 22 "encoding/json" 23 "fmt" 24 "os" 25 "path" 26 "testing" 27 28 "google.golang.org/grpc/internal/xds/bootstrap" 29 "google.golang.org/grpc/testdata" 30 ) 31 32 // DefaultFileWatcherConfig is a helper function to create a default certificate 33 // provider plugin configuration. The test is expected to have setup the files 34 // appropriately before this configuration is used to instantiate providers. 35 func DefaultFileWatcherConfig(certPath, keyPath, caPath string) json.RawMessage { 36 return json.RawMessage(fmt.Sprintf(`{ 37 "plugin_name": "file_watcher", 38 "config": { 39 "certificate_file": %q, 40 "private_key_file": %q, 41 "ca_certificate_file": %q, 42 "refresh_interval": "600s" 43 } 44 }`, certPath, keyPath, caPath)) 45 } 46 47 // DefaultBootstrapContents creates a default bootstrap configuration with the 48 // given node ID and server URI. It also creates certificate provider 49 // configuration and sets the listener resource name template to be used on the 50 // server side. 51 func DefaultBootstrapContents(t *testing.T, nodeID, serverURI string) []byte { 52 t.Helper() 53 54 // Create a directory to hold certs and key files used on the server side. 55 serverDir, err := createTmpDirWithCerts("testServerSideXDS*", "x509/server1_cert.pem", "x509/server1_key.pem", "x509/client_ca_cert.pem") 56 if err != nil { 57 t.Fatalf("Failed to create bootstrap configuration: %v", err) 58 } 59 60 // Create a directory to hold certs and key files used on the client side. 61 clientDir, err := createTmpDirWithCerts("testClientSideXDS*", "x509/client1_cert.pem", "x509/client1_key.pem", "x509/server_ca_cert.pem") 62 if err != nil { 63 t.Fatalf("Failed to create bootstrap configuration: %v", err) 64 } 65 66 // Create certificate providers section of the bootstrap config with entries 67 // for both the client and server sides. 68 cpc := map[string]json.RawMessage{ 69 ServerSideCertProviderInstance: DefaultFileWatcherConfig(path.Join(serverDir, certFile), path.Join(serverDir, keyFile), path.Join(serverDir, rootFile)), 70 ClientSideCertProviderInstance: DefaultFileWatcherConfig(path.Join(clientDir, certFile), path.Join(clientDir, keyFile), path.Join(clientDir, rootFile)), 71 } 72 73 // Create the bootstrap configuration. 74 bs, err := bootstrap.NewContentsForTesting(bootstrap.ConfigOptionsForTesting{ 75 Servers: []byte(fmt.Sprintf(`[{ 76 "server_uri": "passthrough:///%s", 77 "channel_creds": [{"type": "insecure"}] 78 }]`, serverURI)), 79 Node: []byte(fmt.Sprintf(`{"id": "%s"}`, nodeID)), 80 CertificateProviders: cpc, 81 ServerListenerResourceNameTemplate: ServerListenerResourceNameTemplate, 82 }) 83 if err != nil { 84 t.Fatalf("Failed to create bootstrap configuration: %v", err) 85 } 86 return bs 87 } 88 89 const ( 90 // Names of files inside tempdir, for certprovider plugin to watch. 91 certFile = "cert.pem" 92 keyFile = "key.pem" 93 rootFile = "ca.pem" 94 ) 95 96 func createTmpFile(src, dst string) error { 97 data, err := os.ReadFile(src) 98 if err != nil { 99 return fmt.Errorf("os.ReadFile(%q) failed: %v", src, err) 100 } 101 if err := os.WriteFile(dst, data, os.ModePerm); err != nil { 102 return fmt.Errorf("os.WriteFile(%q) failed: %v", dst, err) 103 } 104 return nil 105 } 106 107 // createTmpDirWithCerts creates a temporary directory under the system default 108 // tempDir with the given dirPattern. It also reads from certSrc, keySrc and 109 // rootSrc files and creates appropriate files under the newly create tempDir. 110 // Returns the path of the created tempDir if successful, and an error 111 // otherwise. 112 func createTmpDirWithCerts(dirPattern, certSrc, keySrc, rootSrc string) (string, error) { 113 // Create a temp directory. Passing an empty string for the first argument 114 // uses the system temp directory. 115 dir, err := os.MkdirTemp("", dirPattern) 116 if err != nil { 117 return "", fmt.Errorf("os.MkdirTemp() failed: %v", err) 118 } 119 120 if err := createTmpFile(testdata.Path(certSrc), path.Join(dir, certFile)); err != nil { 121 return "", err 122 } 123 if err := createTmpFile(testdata.Path(keySrc), path.Join(dir, keyFile)); err != nil { 124 return "", err 125 } 126 if err := createTmpFile(testdata.Path(rootSrc), path.Join(dir, rootFile)); err != nil { 127 return "", err 128 } 129 return dir, nil 130 }