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 }