github.com/m-lab/locate@v0.17.6/secrets/load_test.go (about)

     1  package secrets
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"testing"
     7  
     8  	secretmanager "cloud.google.com/go/secretmanager/apiv1"
     9  	"github.com/googleapis/gax-go"
    10  	"github.com/m-lab/locate/prometheus"
    11  	"github.com/prometheus/common/config"
    12  	"google.golang.org/api/iterator"
    13  	secretmanagerpb "google.golang.org/genproto/googleapis/cloud/secretmanager/v1"
    14  )
    15  
    16  type fakeSecretClient struct {
    17  	idx     int
    18  	data    [][]byte
    19  	wantErr bool
    20  }
    21  
    22  func (f *fakeSecretClient) AccessSecretVersion(ctx context.Context, req *secretmanagerpb.AccessSecretVersionRequest, opts ...gax.CallOption) (*secretmanagerpb.AccessSecretVersionResponse, error) {
    23  	if f.wantErr {
    24  		return nil, fmt.Errorf("fake-error")
    25  	}
    26  
    27  	defer f.incrementIdx()
    28  
    29  	return &secretmanagerpb.AccessSecretVersionResponse{
    30  		Name: "fake-secret",
    31  		Payload: &secretmanagerpb.SecretPayload{
    32  			Data: f.data[f.idx],
    33  		},
    34  	}, nil
    35  }
    36  
    37  func (f *fakeSecretClient) ListSecretVersions(ctx context.Context, req *secretmanagerpb.ListSecretVersionsRequest, opts ...gax.CallOption) *secretmanager.SecretVersionIterator {
    38  	return &secretmanager.SecretVersionIterator{}
    39  }
    40  
    41  func (f *fakeSecretClient) incrementIdx() {
    42  	f.idx = f.idx + 1
    43  }
    44  
    45  type fakeIter struct {
    46  	idx      int
    47  	versions []*secretmanagerpb.SecretVersion
    48  	wantErr  bool
    49  }
    50  
    51  func (f *fakeIter) Next(it *secretmanager.SecretVersionIterator) (*secretmanagerpb.SecretVersion, error) {
    52  	if f.wantErr {
    53  		return nil, fmt.Errorf("fake-error")
    54  	}
    55  
    56  	defer f.incrementIdx()
    57  
    58  	if f.idx == len(f.versions) {
    59  		return nil, iterator.Done
    60  	}
    61  	return &secretmanagerpb.SecretVersion{
    62  		Name:  f.versions[f.idx].Name,
    63  		State: f.versions[f.idx].State,
    64  	}, nil
    65  }
    66  
    67  func (f *fakeIter) incrementIdx() {
    68  	f.idx = f.idx + 1
    69  }
    70  
    71  func Test_getSecret(t *testing.T) {
    72  	ctx := context.Background()
    73  
    74  	var secretData [][]byte
    75  	secretData = append(secretData, []byte("fake-secret"))
    76  
    77  	tests := []struct {
    78  		wantErr bool
    79  	}{
    80  		{
    81  			wantErr: false,
    82  		},
    83  		{
    84  			wantErr: true,
    85  		},
    86  	}
    87  
    88  	for _, tt := range tests {
    89  		client := &fakeSecretClient{
    90  			data:    secretData,
    91  			wantErr: tt.wantErr,
    92  		}
    93  		cfg := NewConfig("mlab-sandbox", client)
    94  		cfg.iter = &fakeIter{}
    95  
    96  		secret, err := cfg.getSecret(ctx, "fake-path")
    97  
    98  		if (err != nil) != tt.wantErr {
    99  			t.Fatalf("Got error: %v, but wantErr is %v", err, tt.wantErr)
   100  			return
   101  		}
   102  
   103  		if !tt.wantErr {
   104  			if string(secret) != string(secretData[0]) {
   105  				t.Fatalf("Expected secret value '%s', but got: %s", string(secretData[0]), string(secret))
   106  			}
   107  		}
   108  	}
   109  }
   110  
   111  func Test_getSecretVersions(t *testing.T) {
   112  	ctx := context.Background()
   113  	client := &fakeSecretClient{}
   114  	cfg := NewConfig("mlab-sandbox", client)
   115  
   116  	tests := []struct {
   117  		name             string
   118  		expectedCount    int
   119  		expectedVersions []string
   120  		versions         []*secretmanagerpb.SecretVersion
   121  		wantErr          bool
   122  		wantIterErr      bool
   123  	}{
   124  		{
   125  			name:          "success",
   126  			expectedCount: 2,
   127  			expectedVersions: []string{
   128  				"secrets/mlab-sandbox/fake-secret/versions/3",
   129  				"secrets/mlab-sandbox/fake-secret/versions/1",
   130  			},
   131  			versions: []*secretmanagerpb.SecretVersion{
   132  				{
   133  					Name:  "secrets/mlab-sandbox/fake-secret/versions/4",
   134  					State: secretmanagerpb.SecretVersion_DISABLED,
   135  				},
   136  				{
   137  					Name:  "secrets/mlab-sandbox/fake-secret/versions/3",
   138  					State: secretmanagerpb.SecretVersion_ENABLED,
   139  				},
   140  				{
   141  					Name:  "secrets/mlab-sandbox/fake-secret/versions/2",
   142  					State: secretmanagerpb.SecretVersion_DESTROYED,
   143  				},
   144  				{
   145  					Name:  "secrets/mlab-sandbox/fake-secret/versions/1",
   146  					State: secretmanagerpb.SecretVersion_ENABLED,
   147  				},
   148  			},
   149  		},
   150  		{
   151  			name: "no-versions-error",
   152  			versions: []*secretmanagerpb.SecretVersion{
   153  				{
   154  					Name:  "secrets/mlab-sandbox/fake-secret/versions/4",
   155  					State: secretmanagerpb.SecretVersion_DISABLED,
   156  				},
   157  			},
   158  			wantErr:     true,
   159  			wantIterErr: false,
   160  		},
   161  		{
   162  			name:        "iterator-error",
   163  			wantErr:     true,
   164  			wantIterErr: true,
   165  		},
   166  	}
   167  
   168  	for _, tt := range tests {
   169  		cfg.iter = &fakeIter{
   170  			wantErr:  tt.wantIterErr,
   171  			versions: tt.versions,
   172  		}
   173  		versions, err := cfg.getSecretVersions(ctx, "test")
   174  
   175  		if (err != nil) != tt.wantErr {
   176  			t.Fatalf("Got error: %v, but wantErr is %v", err, tt.wantErr)
   177  			return
   178  		}
   179  
   180  		if len(versions) != tt.expectedCount {
   181  			t.Fatalf("Expected %d secret versions, but got %d", tt.expectedCount, len(versions))
   182  		}
   183  
   184  		for i, v := range tt.expectedVersions {
   185  			if v != versions[i] {
   186  				t.Fatalf("Expected versions:\n\n%v\n\n...but got:\n\n%v", tt.expectedVersions, versions)
   187  			}
   188  		}
   189  	}
   190  }
   191  
   192  func Test_LoadSigner(t *testing.T) {
   193  	ctx := context.Background()
   194  
   195  	var signerKeys [][]byte
   196  
   197  	signerData := `
   198  		{
   199  			"use": "sig",
   200  			"kty": "OKP",
   201  			"kid": "fake_20210721",
   202  			"crv": "Ed25519",
   203  			"alg": "EdDSA",
   204  			"x": "abcde-abcd-abcdefghijklmnopqrstuv-abcdefghi",
   205  			"d": "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqr"
   206  		}
   207  	`
   208  	signerKeys = append(signerKeys, []byte(signerData))
   209  
   210  	tests := []struct {
   211  		name    string
   212  		client  SecretClient
   213  		iter    iter
   214  		wantErr bool
   215  	}{
   216  		{
   217  			name: "success",
   218  			client: &fakeSecretClient{
   219  				data:    signerKeys,
   220  				wantErr: false,
   221  			},
   222  			iter: &fakeIter{
   223  				versions: []*secretmanagerpb.SecretVersion{
   224  					{
   225  						Name:  "secrets/mlab-sandbox/fake-secret/versions/4",
   226  						State: secretmanagerpb.SecretVersion_ENABLED,
   227  					},
   228  				},
   229  			},
   230  			wantErr: false,
   231  		},
   232  		{
   233  			name: "get-secret-versions-error",
   234  			client: &fakeSecretClient{
   235  				wantErr: false,
   236  			},
   237  			iter: &fakeIter{
   238  				wantErr: true,
   239  				versions: []*secretmanagerpb.SecretVersion{
   240  					{
   241  						Name:  "secrets/mlab-sandbox/fake-secret/versions/2",
   242  						State: secretmanagerpb.SecretVersion_DISABLED,
   243  					},
   244  				},
   245  			},
   246  			wantErr: true,
   247  		},
   248  		{
   249  			name: "get-secret-error",
   250  			client: &fakeSecretClient{
   251  				wantErr: true,
   252  			},
   253  			iter: &fakeIter{
   254  				versions: []*secretmanagerpb.SecretVersion{
   255  					{
   256  						Name:  "secrets/mlab-sandbox/fake-secret/versions/2",
   257  						State: secretmanagerpb.SecretVersion_ENABLED,
   258  					},
   259  				},
   260  			},
   261  			wantErr: true,
   262  		},
   263  	}
   264  
   265  	for _, tt := range tests {
   266  		cfg := NewConfig("mlab-sandbox", tt.client)
   267  		cfg.iter = tt.iter
   268  		_, err := cfg.LoadSigner(ctx, "test")
   269  
   270  		if (err != nil) != tt.wantErr {
   271  			t.Fatalf("Got error: %v, but wantErr is %v", err, tt.wantErr)
   272  		}
   273  	}
   274  }
   275  
   276  func Test_LoadVerifier(t *testing.T) {
   277  	ctx := context.Background()
   278  
   279  	var verifyKeys [][]byte
   280  
   281  	verifyData0 := `
   282  		{
   283  			"use": "sig",
   284  			"kty": "OKP",
   285  			"kid": "fake0_20210721",
   286  			"crv": "Ed25519",
   287  			"alg": "EdDSA",
   288  			"x": "abcde-abcd-abcdefghijklmnopqrstuv-abcdefghi"
   289  		}
   290  	`
   291  	verifyKeys = append(verifyKeys, []byte(verifyData0))
   292  
   293  	verifyData1 := `
   294  		{
   295  			"use": "sig",
   296  			"kty": "OKP",
   297  			"kid": "fake1_20210721",
   298  			"crv": "Ed25519",
   299  			"alg": "EdDSA",
   300  			"x": "abcde-abcd-abcdefghijklmnopqrstuv-abcdefghi"
   301  		}
   302  	`
   303  	verifyKeys = append(verifyKeys, []byte(verifyData1))
   304  
   305  	tests := []struct {
   306  		name    string
   307  		client  SecretClient
   308  		iter    iter
   309  		wantErr bool
   310  	}{
   311  		{
   312  			name: "success",
   313  			client: &fakeSecretClient{
   314  				data:    verifyKeys,
   315  				wantErr: false,
   316  			},
   317  			iter: &fakeIter{
   318  				versions: []*secretmanagerpb.SecretVersion{
   319  					{
   320  						Name:  "secrets/mlab-sandbox/fake-secret/versions/4",
   321  						State: secretmanagerpb.SecretVersion_ENABLED,
   322  					},
   323  					{
   324  						Name:  "secrets/mlab-sandbox/fake-secret/versions/2",
   325  						State: secretmanagerpb.SecretVersion_ENABLED,
   326  					},
   327  				},
   328  			},
   329  			wantErr: false,
   330  		},
   331  		{
   332  			name: "get-secret-versions-error",
   333  			client: &fakeSecretClient{
   334  				wantErr: false,
   335  			},
   336  			iter: &fakeIter{
   337  				wantErr: true,
   338  				versions: []*secretmanagerpb.SecretVersion{
   339  					{
   340  						Name:  "secrets/mlab-sandbox/fake-secret/versions/2",
   341  						State: secretmanagerpb.SecretVersion_DISABLED,
   342  					},
   343  				},
   344  			},
   345  			wantErr: true,
   346  		},
   347  		{
   348  			name: "get-secret-error",
   349  			client: &fakeSecretClient{
   350  				wantErr: true,
   351  			},
   352  			iter: &fakeIter{
   353  				versions: []*secretmanagerpb.SecretVersion{
   354  					{
   355  						Name:  "secrets/mlab-sandbox/fake-secret/versions/2",
   356  						State: secretmanagerpb.SecretVersion_ENABLED,
   357  					},
   358  				},
   359  			},
   360  			wantErr: true,
   361  		},
   362  	}
   363  
   364  	for _, tt := range tests {
   365  		cfg := NewConfig("mlab-sandbox", tt.client)
   366  		cfg.iter = tt.iter
   367  
   368  		_, err := cfg.LoadVerifier(ctx, "test2")
   369  
   370  		if (err != nil) != tt.wantErr {
   371  			t.Fatalf("Got error: %v, but wantErr is %v", err, tt.wantErr)
   372  		}
   373  	}
   374  }
   375  
   376  func TestConfig_LoadPrometheus(t *testing.T) {
   377  	ctx := context.Background()
   378  
   379  	secretUser := "fake-user"
   380  	secretPass := "fake-pass"
   381  	secretData := [][]byte{
   382  		[]byte(secretUser), []byte(secretPass),
   383  	}
   384  
   385  	tests := []struct {
   386  		name    string
   387  		client  SecretClient
   388  		want    *prometheus.Credentials
   389  		wantErr bool
   390  	}{
   391  		{
   392  			name: "success",
   393  			client: &fakeSecretClient{
   394  				data: secretData,
   395  			},
   396  			want: &prometheus.Credentials{
   397  				Username: secretUser,
   398  				Password: config.Secret(secretPass),
   399  			},
   400  			wantErr: false,
   401  		},
   402  		{
   403  			name: "get-secret-error",
   404  			client: &fakeSecretClient{
   405  				wantErr: true,
   406  			},
   407  			wantErr: true,
   408  		},
   409  	}
   410  	for _, tt := range tests {
   411  		t.Run(tt.name, func(t *testing.T) {
   412  			cfg := NewConfig("mlab-sandbox", tt.client)
   413  
   414  			got, err := cfg.LoadPrometheus(ctx, "fake-user", "fake-pass")
   415  
   416  			if (err != nil) != tt.wantErr {
   417  				t.Errorf("Config.LoadPrometheus() error = %v, wantErr %v", err, tt.wantErr)
   418  				return
   419  			}
   420  
   421  			if !tt.wantErr {
   422  				if got.Username != tt.want.Username || got.Password != tt.want.Password {
   423  					t.Errorf("Config.LoadPrometheus() got = %v, want = %v", got, tt.want)
   424  				}
   425  			}
   426  		})
   427  	}
   428  }