github.com/djenriquez/nomad-1@v0.8.1/command/agent/acl_endpoint_test.go (about) 1 package agent 2 3 import ( 4 "net/http" 5 "net/http/httptest" 6 "testing" 7 8 "github.com/hashicorp/nomad/nomad/mock" 9 "github.com/hashicorp/nomad/nomad/structs" 10 "github.com/stretchr/testify/assert" 11 ) 12 13 func TestHTTP_ACLPolicyList(t *testing.T) { 14 t.Parallel() 15 httpACLTest(t, nil, func(s *TestAgent) { 16 p1 := mock.ACLPolicy() 17 p2 := mock.ACLPolicy() 18 p3 := mock.ACLPolicy() 19 args := structs.ACLPolicyUpsertRequest{ 20 Policies: []*structs.ACLPolicy{p1, p2, p3}, 21 WriteRequest: structs.WriteRequest{ 22 Region: "global", 23 AuthToken: s.RootToken.SecretID, 24 }, 25 } 26 var resp structs.GenericResponse 27 if err := s.Agent.RPC("ACL.UpsertPolicies", &args, &resp); err != nil { 28 t.Fatalf("err: %v", err) 29 } 30 31 // Make the HTTP request 32 req, err := http.NewRequest("GET", "/v1/acl/policies", nil) 33 if err != nil { 34 t.Fatalf("err: %v", err) 35 } 36 respW := httptest.NewRecorder() 37 setToken(req, s.RootToken) 38 39 // Make the request 40 obj, err := s.Server.ACLPoliciesRequest(respW, req) 41 if err != nil { 42 t.Fatalf("err: %v", err) 43 } 44 45 // Check for the index 46 if respW.HeaderMap.Get("X-Nomad-Index") == "" { 47 t.Fatalf("missing index") 48 } 49 if respW.HeaderMap.Get("X-Nomad-KnownLeader") != "true" { 50 t.Fatalf("missing known leader") 51 } 52 if respW.HeaderMap.Get("X-Nomad-LastContact") == "" { 53 t.Fatalf("missing last contact") 54 } 55 56 // Check the output 57 n := obj.([]*structs.ACLPolicyListStub) 58 if len(n) != 3 { 59 t.Fatalf("bad: %#v", n) 60 } 61 }) 62 } 63 64 func TestHTTP_ACLPolicyQuery(t *testing.T) { 65 t.Parallel() 66 httpACLTest(t, nil, func(s *TestAgent) { 67 p1 := mock.ACLPolicy() 68 args := structs.ACLPolicyUpsertRequest{ 69 Policies: []*structs.ACLPolicy{p1}, 70 WriteRequest: structs.WriteRequest{ 71 Region: "global", 72 AuthToken: s.RootToken.SecretID, 73 }, 74 } 75 var resp structs.GenericResponse 76 if err := s.Agent.RPC("ACL.UpsertPolicies", &args, &resp); err != nil { 77 t.Fatalf("err: %v", err) 78 } 79 80 // Make the HTTP request 81 req, err := http.NewRequest("GET", "/v1/acl/policy/"+p1.Name, nil) 82 if err != nil { 83 t.Fatalf("err: %v", err) 84 } 85 respW := httptest.NewRecorder() 86 setToken(req, s.RootToken) 87 88 // Make the request 89 obj, err := s.Server.ACLPolicySpecificRequest(respW, req) 90 if err != nil { 91 t.Fatalf("err: %v", err) 92 } 93 94 // Check for the index 95 if respW.HeaderMap.Get("X-Nomad-Index") == "" { 96 t.Fatalf("missing index") 97 } 98 if respW.HeaderMap.Get("X-Nomad-KnownLeader") != "true" { 99 t.Fatalf("missing known leader") 100 } 101 if respW.HeaderMap.Get("X-Nomad-LastContact") == "" { 102 t.Fatalf("missing last contact") 103 } 104 105 // Check the output 106 n := obj.(*structs.ACLPolicy) 107 if n.Name != p1.Name { 108 t.Fatalf("bad: %#v", n) 109 } 110 }) 111 } 112 113 func TestHTTP_ACLPolicyCreate(t *testing.T) { 114 t.Parallel() 115 httpACLTest(t, nil, func(s *TestAgent) { 116 // Make the HTTP request 117 p1 := mock.ACLPolicy() 118 buf := encodeReq(p1) 119 req, err := http.NewRequest("PUT", "/v1/acl/policy/"+p1.Name, buf) 120 if err != nil { 121 t.Fatalf("err: %v", err) 122 } 123 respW := httptest.NewRecorder() 124 setToken(req, s.RootToken) 125 126 // Make the request 127 obj, err := s.Server.ACLPolicySpecificRequest(respW, req) 128 assert.Nil(t, err) 129 assert.Nil(t, obj) 130 131 // Check for the index 132 if respW.HeaderMap.Get("X-Nomad-Index") == "" { 133 t.Fatalf("missing index") 134 } 135 136 // Check policy was created 137 state := s.Agent.server.State() 138 out, err := state.ACLPolicyByName(nil, p1.Name) 139 assert.Nil(t, err) 140 assert.NotNil(t, out) 141 142 p1.CreateIndex, p1.ModifyIndex = out.CreateIndex, out.ModifyIndex 143 assert.Equal(t, p1.Name, out.Name) 144 assert.Equal(t, p1, out) 145 }) 146 } 147 148 func TestHTTP_ACLPolicyDelete(t *testing.T) { 149 t.Parallel() 150 httpACLTest(t, nil, func(s *TestAgent) { 151 p1 := mock.ACLPolicy() 152 args := structs.ACLPolicyUpsertRequest{ 153 Policies: []*structs.ACLPolicy{p1}, 154 WriteRequest: structs.WriteRequest{ 155 Region: "global", 156 AuthToken: s.RootToken.SecretID, 157 }, 158 } 159 var resp structs.GenericResponse 160 if err := s.Agent.RPC("ACL.UpsertPolicies", &args, &resp); err != nil { 161 t.Fatalf("err: %v", err) 162 } 163 164 // Make the HTTP request 165 req, err := http.NewRequest("DELETE", "/v1/acl/policy/"+p1.Name, nil) 166 if err != nil { 167 t.Fatalf("err: %v", err) 168 } 169 respW := httptest.NewRecorder() 170 setToken(req, s.RootToken) 171 172 // Make the request 173 obj, err := s.Server.ACLPolicySpecificRequest(respW, req) 174 assert.Nil(t, err) 175 assert.Nil(t, obj) 176 177 // Check for the index 178 if respW.HeaderMap.Get("X-Nomad-Index") == "" { 179 t.Fatalf("missing index") 180 } 181 182 // Check policy was created 183 state := s.Agent.server.State() 184 out, err := state.ACLPolicyByName(nil, p1.Name) 185 assert.Nil(t, err) 186 assert.Nil(t, out) 187 }) 188 } 189 190 func TestHTTP_ACLTokenBootstrap(t *testing.T) { 191 t.Parallel() 192 conf := func(c *Config) { 193 c.ACL.Enabled = true 194 c.ACL.PolicyTTL = 0 // Special flag to disable auto-bootstrap 195 } 196 httpTest(t, conf, func(s *TestAgent) { 197 // Make the HTTP request 198 req, err := http.NewRequest("PUT", "/v1/acl/bootstrap", nil) 199 if err != nil { 200 t.Fatalf("err: %v", err) 201 } 202 respW := httptest.NewRecorder() 203 204 // Make the request 205 obj, err := s.Server.ACLTokenBootstrap(respW, req) 206 if err != nil { 207 t.Fatalf("err: %v", err) 208 } 209 210 // Check for the index 211 if respW.HeaderMap.Get("X-Nomad-Index") == "" { 212 t.Fatalf("missing index") 213 } 214 215 // Check the output 216 n := obj.(*structs.ACLToken) 217 assert.NotNil(t, n) 218 assert.Equal(t, "Bootstrap Token", n.Name) 219 }) 220 } 221 222 func TestHTTP_ACLTokenList(t *testing.T) { 223 t.Parallel() 224 httpACLTest(t, nil, func(s *TestAgent) { 225 p1 := mock.ACLToken() 226 p1.AccessorID = "" 227 p2 := mock.ACLToken() 228 p2.AccessorID = "" 229 p3 := mock.ACLToken() 230 p3.AccessorID = "" 231 args := structs.ACLTokenUpsertRequest{ 232 Tokens: []*structs.ACLToken{p1, p2, p3}, 233 WriteRequest: structs.WriteRequest{ 234 Region: "global", 235 AuthToken: s.RootToken.SecretID, 236 }, 237 } 238 var resp structs.ACLTokenUpsertResponse 239 if err := s.Agent.RPC("ACL.UpsertTokens", &args, &resp); err != nil { 240 t.Fatalf("err: %v", err) 241 } 242 243 // Make the HTTP request 244 req, err := http.NewRequest("GET", "/v1/acl/tokens", nil) 245 if err != nil { 246 t.Fatalf("err: %v", err) 247 } 248 respW := httptest.NewRecorder() 249 setToken(req, s.RootToken) 250 251 // Make the request 252 obj, err := s.Server.ACLTokensRequest(respW, req) 253 if err != nil { 254 t.Fatalf("err: %v", err) 255 } 256 257 // Check for the index 258 if respW.HeaderMap.Get("X-Nomad-Index") == "" { 259 t.Fatalf("missing index") 260 } 261 if respW.HeaderMap.Get("X-Nomad-KnownLeader") != "true" { 262 t.Fatalf("missing known leader") 263 } 264 if respW.HeaderMap.Get("X-Nomad-LastContact") == "" { 265 t.Fatalf("missing last contact") 266 } 267 268 // Check the output (includes bootstrap token) 269 n := obj.([]*structs.ACLTokenListStub) 270 if len(n) != 4 { 271 t.Fatalf("bad: %#v", n) 272 } 273 }) 274 } 275 276 func TestHTTP_ACLTokenQuery(t *testing.T) { 277 t.Parallel() 278 httpACLTest(t, nil, func(s *TestAgent) { 279 p1 := mock.ACLToken() 280 p1.AccessorID = "" 281 args := structs.ACLTokenUpsertRequest{ 282 Tokens: []*structs.ACLToken{p1}, 283 WriteRequest: structs.WriteRequest{ 284 Region: "global", 285 AuthToken: s.RootToken.SecretID, 286 }, 287 } 288 var resp structs.ACLTokenUpsertResponse 289 if err := s.Agent.RPC("ACL.UpsertTokens", &args, &resp); err != nil { 290 t.Fatalf("err: %v", err) 291 } 292 out := resp.Tokens[0] 293 294 // Make the HTTP request 295 req, err := http.NewRequest("GET", "/v1/acl/token/"+out.AccessorID, nil) 296 if err != nil { 297 t.Fatalf("err: %v", err) 298 } 299 respW := httptest.NewRecorder() 300 setToken(req, s.RootToken) 301 302 // Make the request 303 obj, err := s.Server.ACLTokenSpecificRequest(respW, req) 304 if err != nil { 305 t.Fatalf("err: %v", err) 306 } 307 308 // Check for the index 309 if respW.HeaderMap.Get("X-Nomad-Index") == "" { 310 t.Fatalf("missing index") 311 } 312 if respW.HeaderMap.Get("X-Nomad-KnownLeader") != "true" { 313 t.Fatalf("missing known leader") 314 } 315 if respW.HeaderMap.Get("X-Nomad-LastContact") == "" { 316 t.Fatalf("missing last contact") 317 } 318 319 // Check the output 320 n := obj.(*structs.ACLToken) 321 assert.Equal(t, out, n) 322 }) 323 } 324 325 func TestHTTP_ACLTokenSelf(t *testing.T) { 326 t.Parallel() 327 httpACLTest(t, nil, func(s *TestAgent) { 328 p1 := mock.ACLToken() 329 p1.AccessorID = "" 330 args := structs.ACLTokenUpsertRequest{ 331 Tokens: []*structs.ACLToken{p1}, 332 WriteRequest: structs.WriteRequest{ 333 Region: "global", 334 AuthToken: s.RootToken.SecretID, 335 }, 336 } 337 var resp structs.ACLTokenUpsertResponse 338 if err := s.Agent.RPC("ACL.UpsertTokens", &args, &resp); err != nil { 339 t.Fatalf("err: %v", err) 340 } 341 out := resp.Tokens[0] 342 343 // Make the HTTP request 344 req, err := http.NewRequest("GET", "/v1/acl/token/self", nil) 345 if err != nil { 346 t.Fatalf("err: %v", err) 347 } 348 respW := httptest.NewRecorder() 349 setToken(req, out) 350 351 // Make the request 352 obj, err := s.Server.ACLTokenSpecificRequest(respW, req) 353 if err != nil { 354 t.Fatalf("err: %v", err) 355 } 356 357 // Check for the index 358 if respW.HeaderMap.Get("X-Nomad-Index") == "" { 359 t.Fatalf("missing index") 360 } 361 if respW.HeaderMap.Get("X-Nomad-KnownLeader") != "true" { 362 t.Fatalf("missing known leader") 363 } 364 if respW.HeaderMap.Get("X-Nomad-LastContact") == "" { 365 t.Fatalf("missing last contact") 366 } 367 368 // Check the output 369 n := obj.(*structs.ACLToken) 370 assert.Equal(t, out, n) 371 }) 372 } 373 374 func TestHTTP_ACLTokenCreate(t *testing.T) { 375 t.Parallel() 376 httpACLTest(t, nil, func(s *TestAgent) { 377 // Make the HTTP request 378 p1 := mock.ACLToken() 379 p1.AccessorID = "" 380 buf := encodeReq(p1) 381 req, err := http.NewRequest("PUT", "/v1/acl/token", buf) 382 if err != nil { 383 t.Fatalf("err: %v", err) 384 } 385 respW := httptest.NewRecorder() 386 setToken(req, s.RootToken) 387 388 // Make the request 389 obj, err := s.Server.ACLTokenSpecificRequest(respW, req) 390 assert.Nil(t, err) 391 assert.NotNil(t, obj) 392 outTK := obj.(*structs.ACLToken) 393 394 // Check for the index 395 if respW.HeaderMap.Get("X-Nomad-Index") == "" { 396 t.Fatalf("missing index") 397 } 398 399 // Check token was created 400 state := s.Agent.server.State() 401 out, err := state.ACLTokenByAccessorID(nil, outTK.AccessorID) 402 assert.Nil(t, err) 403 assert.NotNil(t, out) 404 assert.Equal(t, outTK, out) 405 }) 406 } 407 408 func TestHTTP_ACLTokenDelete(t *testing.T) { 409 t.Parallel() 410 httpACLTest(t, nil, func(s *TestAgent) { 411 p1 := mock.ACLToken() 412 p1.AccessorID = "" 413 args := structs.ACLTokenUpsertRequest{ 414 Tokens: []*structs.ACLToken{p1}, 415 WriteRequest: structs.WriteRequest{ 416 Region: "global", 417 AuthToken: s.RootToken.SecretID, 418 }, 419 } 420 var resp structs.ACLTokenUpsertResponse 421 if err := s.Agent.RPC("ACL.UpsertTokens", &args, &resp); err != nil { 422 t.Fatalf("err: %v", err) 423 } 424 ID := resp.Tokens[0].AccessorID 425 426 // Make the HTTP request 427 req, err := http.NewRequest("DELETE", "/v1/acl/token/"+ID, nil) 428 if err != nil { 429 t.Fatalf("err: %v", err) 430 } 431 respW := httptest.NewRecorder() 432 setToken(req, s.RootToken) 433 434 // Make the request 435 obj, err := s.Server.ACLTokenSpecificRequest(respW, req) 436 assert.Nil(t, err) 437 assert.Nil(t, obj) 438 439 // Check for the index 440 if respW.HeaderMap.Get("X-Nomad-Index") == "" { 441 t.Fatalf("missing index") 442 } 443 444 // Check token was created 445 state := s.Agent.server.State() 446 out, err := state.ACLTokenByAccessorID(nil, ID) 447 assert.Nil(t, err) 448 assert.Nil(t, out) 449 }) 450 }