github.com/djenriquez/nomad-1@v0.8.1/client/vaultclient/vaultclient_test.go (about)

     1  package vaultclient
     2  
     3  import (
     4  	"log"
     5  	"os"
     6  	"strings"
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/hashicorp/nomad/client/config"
    11  	"github.com/hashicorp/nomad/testutil"
    12  	vaultapi "github.com/hashicorp/vault/api"
    13  )
    14  
    15  func TestVaultClient_TokenRenewals(t *testing.T) {
    16  	t.Parallel()
    17  	v := testutil.NewTestVault(t)
    18  	defer v.Stop()
    19  
    20  	logger := log.New(os.Stderr, "TEST: ", log.Lshortfile|log.LstdFlags)
    21  	v.Config.ConnectionRetryIntv = 100 * time.Millisecond
    22  	v.Config.TaskTokenTTL = "4s"
    23  	c, err := NewVaultClient(v.Config, logger, nil)
    24  	if err != nil {
    25  		t.Fatalf("failed to build vault client: %v", err)
    26  	}
    27  
    28  	c.Start()
    29  	defer c.Stop()
    30  
    31  	// Sleep a little while to ensure that the renewal loop is active
    32  	time.Sleep(time.Duration(testutil.TestMultiplier()) * time.Second)
    33  
    34  	tcr := &vaultapi.TokenCreateRequest{
    35  		Policies:    []string{"foo", "bar"},
    36  		TTL:         "2s",
    37  		DisplayName: "derived-for-task",
    38  		Renewable:   new(bool),
    39  	}
    40  	*tcr.Renewable = true
    41  
    42  	num := 5
    43  	tokens := make([]string, num)
    44  	for i := 0; i < num; i++ {
    45  		c.client.SetToken(v.Config.Token)
    46  
    47  		if err := c.client.SetAddress(v.Config.Addr); err != nil {
    48  			t.Fatal(err)
    49  		}
    50  
    51  		secret, err := c.client.Auth().Token().Create(tcr)
    52  		if err != nil {
    53  			t.Fatalf("failed to create vault token: %v", err)
    54  		}
    55  
    56  		if secret == nil || secret.Auth == nil || secret.Auth.ClientToken == "" {
    57  			t.Fatal("failed to derive a wrapped vault token")
    58  		}
    59  
    60  		tokens[i] = secret.Auth.ClientToken
    61  
    62  		errCh, err := c.RenewToken(tokens[i], secret.Auth.LeaseDuration)
    63  		if err != nil {
    64  			t.Fatalf("Unexpected error: %v", err)
    65  		}
    66  
    67  		go func(errCh <-chan error) {
    68  			for {
    69  				select {
    70  				case err := <-errCh:
    71  					if err != nil {
    72  						t.Fatalf("error while renewing the token: %v", err)
    73  					}
    74  				}
    75  			}
    76  		}(errCh)
    77  	}
    78  
    79  	if c.heap.Length() != num {
    80  		t.Fatalf("bad: heap length: expected: %d, actual: %d", num, c.heap.Length())
    81  	}
    82  
    83  	time.Sleep(time.Duration(testutil.TestMultiplier()) * time.Second)
    84  
    85  	for i := 0; i < num; i++ {
    86  		if err := c.StopRenewToken(tokens[i]); err != nil {
    87  			t.Fatal(err)
    88  		}
    89  	}
    90  
    91  	if c.heap.Length() != 0 {
    92  		t.Fatalf("bad: heap length: expected: 0, actual: %d", c.heap.Length())
    93  	}
    94  }
    95  
    96  func TestVaultClient_Heap(t *testing.T) {
    97  	t.Parallel()
    98  	tr := true
    99  	conf := config.DefaultConfig()
   100  	conf.VaultConfig.Enabled = &tr
   101  	conf.VaultConfig.Token = "testvaulttoken"
   102  	conf.VaultConfig.TaskTokenTTL = "10s"
   103  
   104  	logger := log.New(os.Stderr, "TEST: ", log.Lshortfile|log.LstdFlags)
   105  	c, err := NewVaultClient(conf.VaultConfig, logger, nil)
   106  	if err != nil {
   107  		t.Fatal(err)
   108  	}
   109  	if c == nil {
   110  		t.Fatal("failed to create vault client")
   111  	}
   112  
   113  	now := time.Now()
   114  
   115  	renewalReq1 := &vaultClientRenewalRequest{
   116  		errCh:     make(chan error, 1),
   117  		id:        "id1",
   118  		increment: 10,
   119  	}
   120  	if err := c.heap.Push(renewalReq1, now.Add(50*time.Second)); err != nil {
   121  		t.Fatal(err)
   122  	}
   123  	if !c.isTracked("id1") {
   124  		t.Fatalf("id1 should have been tracked")
   125  	}
   126  
   127  	renewalReq2 := &vaultClientRenewalRequest{
   128  		errCh:     make(chan error, 1),
   129  		id:        "id2",
   130  		increment: 10,
   131  	}
   132  	if err := c.heap.Push(renewalReq2, now.Add(40*time.Second)); err != nil {
   133  		t.Fatal(err)
   134  	}
   135  	if !c.isTracked("id2") {
   136  		t.Fatalf("id2 should have been tracked")
   137  	}
   138  
   139  	renewalReq3 := &vaultClientRenewalRequest{
   140  		errCh:     make(chan error, 1),
   141  		id:        "id3",
   142  		increment: 10,
   143  	}
   144  	if err := c.heap.Push(renewalReq3, now.Add(60*time.Second)); err != nil {
   145  		t.Fatal(err)
   146  	}
   147  	if !c.isTracked("id3") {
   148  		t.Fatalf("id3 should have been tracked")
   149  	}
   150  
   151  	// Reading elements should yield id2, id1 and id3 in order
   152  	req, _ := c.nextRenewal()
   153  	if req != renewalReq2 {
   154  		t.Fatalf("bad: expected: %#v, actual: %#v", renewalReq2, req)
   155  	}
   156  	if err := c.heap.Update(req, now.Add(70*time.Second)); err != nil {
   157  		t.Fatal(err)
   158  	}
   159  
   160  	req, _ = c.nextRenewal()
   161  	if req != renewalReq1 {
   162  		t.Fatalf("bad: expected: %#v, actual: %#v", renewalReq1, req)
   163  	}
   164  	if err := c.heap.Update(req, now.Add(80*time.Second)); err != nil {
   165  		t.Fatal(err)
   166  	}
   167  
   168  	req, _ = c.nextRenewal()
   169  	if req != renewalReq3 {
   170  		t.Fatalf("bad: expected: %#v, actual: %#v", renewalReq3, req)
   171  	}
   172  	if err := c.heap.Update(req, now.Add(90*time.Second)); err != nil {
   173  		t.Fatal(err)
   174  	}
   175  
   176  	if err := c.StopRenewToken("id1"); err != nil {
   177  		t.Fatal(err)
   178  	}
   179  
   180  	if err := c.StopRenewToken("id2"); err != nil {
   181  		t.Fatal(err)
   182  	}
   183  
   184  	if err := c.StopRenewToken("id3"); err != nil {
   185  		t.Fatal(err)
   186  	}
   187  
   188  	if c.isTracked("id1") {
   189  		t.Fatalf("id1 should not have been tracked")
   190  	}
   191  
   192  	if c.isTracked("id1") {
   193  		t.Fatalf("id1 should not have been tracked")
   194  	}
   195  
   196  	if c.isTracked("id1") {
   197  		t.Fatalf("id1 should not have been tracked")
   198  	}
   199  
   200  }
   201  
   202  func TestVaultClient_RenewNonRenewableLease(t *testing.T) {
   203  	t.Parallel()
   204  	v := testutil.NewTestVault(t)
   205  	defer v.Stop()
   206  
   207  	logger := log.New(os.Stderr, "TEST: ", log.Lshortfile|log.LstdFlags)
   208  	v.Config.ConnectionRetryIntv = 100 * time.Millisecond
   209  	v.Config.TaskTokenTTL = "4s"
   210  	c, err := NewVaultClient(v.Config, logger, nil)
   211  	if err != nil {
   212  		t.Fatalf("failed to build vault client: %v", err)
   213  	}
   214  
   215  	c.Start()
   216  	defer c.Stop()
   217  
   218  	// Sleep a little while to ensure that the renewal loop is active
   219  	time.Sleep(time.Duration(testutil.TestMultiplier()) * time.Second)
   220  
   221  	tcr := &vaultapi.TokenCreateRequest{
   222  		Policies:    []string{"foo", "bar"},
   223  		TTL:         "2s",
   224  		DisplayName: "derived-for-task",
   225  		Renewable:   new(bool),
   226  	}
   227  
   228  	c.client.SetToken(v.Config.Token)
   229  
   230  	if err := c.client.SetAddress(v.Config.Addr); err != nil {
   231  		t.Fatal(err)
   232  	}
   233  
   234  	secret, err := c.client.Auth().Token().Create(tcr)
   235  	if err != nil {
   236  		t.Fatalf("failed to create vault token: %v", err)
   237  	}
   238  
   239  	if secret == nil || secret.Auth == nil || secret.Auth.ClientToken == "" {
   240  		t.Fatal("failed to derive a wrapped vault token")
   241  	}
   242  
   243  	_, err = c.RenewToken(secret.Auth.ClientToken, secret.Auth.LeaseDuration)
   244  	if err == nil {
   245  		t.Fatalf("expected error, got nil")
   246  	} else if !strings.Contains(err.Error(), "lease is not renewable") {
   247  		t.Fatalf("expected \"%s\" in error message, got \"%v\"", "lease is not renewable", err)
   248  	}
   249  }
   250  
   251  func TestVaultClient_RenewNonexistentLease(t *testing.T) {
   252  	t.Parallel()
   253  	v := testutil.NewTestVault(t)
   254  	defer v.Stop()
   255  
   256  	logger := log.New(os.Stderr, "TEST: ", log.Lshortfile|log.LstdFlags)
   257  	v.Config.ConnectionRetryIntv = 100 * time.Millisecond
   258  	v.Config.TaskTokenTTL = "4s"
   259  	c, err := NewVaultClient(v.Config, logger, nil)
   260  	if err != nil {
   261  		t.Fatalf("failed to build vault client: %v", err)
   262  	}
   263  
   264  	c.Start()
   265  	defer c.Stop()
   266  
   267  	// Sleep a little while to ensure that the renewal loop is active
   268  	time.Sleep(time.Duration(testutil.TestMultiplier()) * time.Second)
   269  
   270  	c.client.SetToken(v.Config.Token)
   271  
   272  	if err := c.client.SetAddress(v.Config.Addr); err != nil {
   273  		t.Fatal(err)
   274  	}
   275  
   276  	_, err = c.RenewToken(c.client.Token(), 10)
   277  	if err == nil {
   278  		t.Fatalf("expected error, got nil")
   279  	} else if !strings.Contains(err.Error(), "lease not found") {
   280  		t.Fatalf("expected \"%s\" in error message, got \"%v\"", "lease not found", err)
   281  	}
   282  }