Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

xds/bootstrap: add testing support to generate config #7326

Merged
merged 5 commits into from
Jun 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 0 additions & 12 deletions admin/test/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,10 @@ import (
"testing"
"time"

"github.com/google/uuid"
"google.golang.org/grpc"
"google.golang.org/grpc/admin"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/internal/testutils/xds/bootstrap"
"google.golang.org/grpc/status"

v3statusgrpc "github.com/envoyproxy/go-control-plane/envoy/service/status/v3"
Expand All @@ -54,16 +52,6 @@ type ExpectedStatusCodes struct {
// RunRegisterTests makes a client, runs the RPCs, and compares the status
// codes.
func RunRegisterTests(t *testing.T, ec ExpectedStatusCodes) {
nodeID := uuid.New().String()
bootstrapCleanup, err := bootstrap.CreateFile(bootstrap.Options{
NodeID: nodeID,
ServerURI: "no.need.for.a.server",
})
if err != nil {
t.Fatal(err)
}
defer bootstrapCleanup()

lis, err := net.Listen("tcp", "localhost:0")
if err != nil {
t.Fatalf("cannot create listener: %v", err)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
*
* Copyright 2022 gRPC authors.
* Copyright 2024 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -13,65 +13,20 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package e2e
package testutils

import (
"crypto/tls"
"crypto/x509"
"fmt"
"os"
"path"
"testing"

"google.golang.org/grpc/credentials"
"google.golang.org/grpc/testdata"
)

const (
// Names of files inside tempdir, for certprovider plugin to watch.
certFile = "cert.pem"
keyFile = "key.pem"
rootFile = "ca.pem"
)

func createTmpFile(src, dst string) error {
data, err := os.ReadFile(src)
if err != nil {
return fmt.Errorf("os.ReadFile(%q) failed: %v", src, err)
}
if err := os.WriteFile(dst, data, os.ModePerm); err != nil {
return fmt.Errorf("os.WriteFile(%q) failed: %v", dst, err)
}
return nil
}

// createTempDirWithFiles creates a temporary directory under the system default
// tempDir with the given dirSuffix. It also reads from certSrc, keySrc and
// rootSrc files are creates appropriate files under the newly create tempDir.
// Returns the name of the created tempDir.
func createTmpDirWithFiles(dirSuffix, certSrc, keySrc, rootSrc string) (string, error) {
// Create a temp directory. Passing an empty string for the first argument
// uses the system temp directory.
dir, err := os.MkdirTemp("", dirSuffix)
if err != nil {
return "", fmt.Errorf("os.MkdirTemp() failed: %v", err)
}

if err := createTmpFile(testdata.Path(certSrc), path.Join(dir, certFile)); err != nil {
return "", err
}
if err := createTmpFile(testdata.Path(keySrc), path.Join(dir, keyFile)); err != nil {
return "", err
}
if err := createTmpFile(testdata.Path(rootSrc), path.Join(dir, rootFile)); err != nil {
return "", err
}
return dir, nil
}

// CreateClientTLSCredentials creates client-side TLS transport credentials
// using certificate and key files from testdata/x509 directory.
func CreateClientTLSCredentials(t *testing.T) credentials.TransportCredentials {
Expand Down
169 changes: 0 additions & 169 deletions internal/testutils/xds/bootstrap/bootstrap.go

This file was deleted.

91 changes: 91 additions & 0 deletions internal/testutils/xds/e2e/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ package e2e
import (
"encoding/json"
"fmt"
"os"
"path"
"testing"

"google.golang.org/grpc/internal/xds/bootstrap"
"google.golang.org/grpc/testdata"
)

// DefaultFileWatcherConfig is a helper function to create a default certificate
Expand All @@ -37,3 +43,88 @@ func DefaultFileWatcherConfig(certPath, keyPath, caPath string) json.RawMessage
}
}`, certPath, keyPath, caPath))
}

// DefaultBootstrapContents creates a default bootstrap configuration with the
// given node ID and server URI. It also creates certificate provider
// configuration and sets the listener resource name template to be used on the
// server side.
func DefaultBootstrapContents(t *testing.T, nodeID, serverURI string) []byte {
t.Helper()

// Create a directory to hold certs and key files used on the server side.
serverDir, err := createTmpDirWithCerts("testServerSideXDS*", "x509/server1_cert.pem", "x509/server1_key.pem", "x509/client_ca_cert.pem")
if err != nil {
t.Fatalf("Failed to create bootstrap configuration: %v", err)
}

// Create a directory to hold certs and key files used on the client side.
clientDir, err := createTmpDirWithCerts("testClientSideXDS*", "x509/client1_cert.pem", "x509/client1_key.pem", "x509/server_ca_cert.pem")
if err != nil {
t.Fatalf("Failed to create bootstrap configuration: %v", err)
}

// Create certificate providers section of the bootstrap config with entries
// for both the client and server sides.
cpc := map[string]json.RawMessage{
ServerSideCertProviderInstance: DefaultFileWatcherConfig(path.Join(serverDir, certFile), path.Join(serverDir, keyFile), path.Join(serverDir, rootFile)),
ClientSideCertProviderInstance: DefaultFileWatcherConfig(path.Join(clientDir, certFile), path.Join(clientDir, keyFile), path.Join(clientDir, rootFile)),
}

// Create the bootstrap configuration.
bs, err := bootstrap.NewContentsForTesting(bootstrap.ConfigOptionsForTesting{
Servers: []json.RawMessage{[]byte(fmt.Sprintf(`{
"server_uri": "passthrough:///%s",
"channel_creds": [{"type": "insecure"}]
}`, serverURI))},
NodeID: nodeID,
CertificateProviders: cpc,
ServerListenerResourceNameTemplate: ServerListenerResourceNameTemplate,
})
if err != nil {
t.Fatalf("Failed to create bootstrap configuration: %v", err)
}
return bs
}

const (
// Names of files inside tempdir, for certprovider plugin to watch.
certFile = "cert.pem"
keyFile = "key.pem"
rootFile = "ca.pem"
)

func createTmpFile(src, dst string) error {
data, err := os.ReadFile(src)
if err != nil {
return fmt.Errorf("os.ReadFile(%q) failed: %v", src, err)
}
if err := os.WriteFile(dst, data, os.ModePerm); err != nil {
return fmt.Errorf("os.WriteFile(%q) failed: %v", dst, err)
}
return nil
}

// createTmpDirWithCerts creates a temporary directory under the system default
// tempDir with the given dirPattern. It also reads from certSrc, keySrc and
// rootSrc files and creates appropriate files under the newly create tempDir.
// Returns the path of the created tempDir if successful, and an error
// otherwise.
func createTmpDirWithCerts(dirPattern, certSrc, keySrc, rootSrc string) (string, error) {
// Create a temp directory. Passing an empty string for the first argument
// uses the system temp directory.
dir, err := os.MkdirTemp("", dirPattern)
if err != nil {
return "", fmt.Errorf("os.MkdirTemp() failed: %v", err)
}

if err := createTmpFile(testdata.Path(certSrc), path.Join(dir, certFile)); err != nil {
return "", err
}
if err := createTmpFile(testdata.Path(keySrc), path.Join(dir, keyFile)); err != nil {
return "", err
}
if err := createTmpFile(testdata.Path(rootSrc), path.Join(dir, rootFile)); err != nil {
return "", err
}
return dir, nil
}
Loading
Loading