github.com/karlem/nomad@v0.10.2-rc1/command/agent/agent_endpoint_test.go (about)

     1  package agent
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"fmt"
     7  	"io/ioutil"
     8  	"net"
     9  	"net/http"
    10  	"net/http/httptest"
    11  	"net/url"
    12  	"strings"
    13  	"testing"
    14  	"time"
    15  
    16  	msgpackrpc "github.com/hashicorp/net-rpc-msgpackrpc"
    17  	"github.com/hashicorp/nomad/acl"
    18  	"github.com/hashicorp/nomad/helper/pool"
    19  	"github.com/hashicorp/nomad/nomad/mock"
    20  	"github.com/hashicorp/nomad/nomad/structs"
    21  	"github.com/hashicorp/nomad/testutil"
    22  	"github.com/stretchr/testify/require"
    23  )
    24  
    25  func TestHTTP_AgentSelf(t *testing.T) {
    26  	t.Parallel()
    27  	require := require.New(t)
    28  
    29  	httpTest(t, nil, func(s *TestAgent) {
    30  		// Make the HTTP request
    31  		req, err := http.NewRequest("GET", "/v1/agent/self", nil)
    32  		require.NoError(err)
    33  		respW := httptest.NewRecorder()
    34  
    35  		// Make the request
    36  		obj, err := s.Server.AgentSelfRequest(respW, req)
    37  		require.NoError(err)
    38  
    39  		// Check the job
    40  		self := obj.(agentSelf)
    41  		require.NotNil(self.Config)
    42  		require.NotNil(self.Config.ACL)
    43  		require.NotEmpty(self.Stats)
    44  
    45  		// Check the Vault config
    46  		require.Empty(self.Config.Vault.Token)
    47  
    48  		// Assign a Vault token and require it is redacted.
    49  		s.Config.Vault.Token = "badc0deb-adc0-deba-dc0d-ebadc0debadc"
    50  		respW = httptest.NewRecorder()
    51  		obj, err = s.Server.AgentSelfRequest(respW, req)
    52  		require.NoError(err)
    53  		self = obj.(agentSelf)
    54  		require.Equal("<redacted>", self.Config.Vault.Token)
    55  
    56  		// Assign a ReplicationToken token and require it is redacted.
    57  		s.Config.ACL.ReplicationToken = "badc0deb-adc0-deba-dc0d-ebadc0debadc"
    58  		respW = httptest.NewRecorder()
    59  		obj, err = s.Server.AgentSelfRequest(respW, req)
    60  		require.NoError(err)
    61  		self = obj.(agentSelf)
    62  		require.Equal("<redacted>", self.Config.ACL.ReplicationToken)
    63  
    64  		// Check the Consul config
    65  		require.Empty(self.Config.Consul.Token)
    66  
    67  		// Assign a Consul token and require it is redacted.
    68  		s.Config.Consul.Token = "badc0deb-adc0-deba-dc0d-ebadc0debadc"
    69  		respW = httptest.NewRecorder()
    70  		obj, err = s.Server.AgentSelfRequest(respW, req)
    71  		require.NoError(err)
    72  		self = obj.(agentSelf)
    73  		require.Equal("<redacted>", self.Config.Consul.Token)
    74  
    75  		// Check the Circonus config
    76  		require.Empty(self.Config.Telemetry.CirconusAPIToken)
    77  
    78  		// Assign a Consul token and require it is redacted.
    79  		s.Config.Telemetry.CirconusAPIToken = "badc0deb-adc0-deba-dc0d-ebadc0debadc"
    80  		respW = httptest.NewRecorder()
    81  		obj, err = s.Server.AgentSelfRequest(respW, req)
    82  		require.NoError(err)
    83  		self = obj.(agentSelf)
    84  		require.Equal("<redacted>", self.Config.Telemetry.CirconusAPIToken)
    85  	})
    86  }
    87  
    88  func TestHTTP_AgentSelf_ACL(t *testing.T) {
    89  	t.Parallel()
    90  	require := require.New(t)
    91  
    92  	httpACLTest(t, nil, func(s *TestAgent) {
    93  		state := s.Agent.server.State()
    94  
    95  		// Make the HTTP request
    96  		req, err := http.NewRequest("GET", "/v1/agent/self", nil)
    97  		require.Nil(err)
    98  
    99  		// Try request without a token and expect failure
   100  		{
   101  			respW := httptest.NewRecorder()
   102  			_, err := s.Server.AgentSelfRequest(respW, req)
   103  			require.NotNil(err)
   104  			require.Equal(err.Error(), structs.ErrPermissionDenied.Error())
   105  		}
   106  
   107  		// Try request with an invalid token and expect failure
   108  		{
   109  			respW := httptest.NewRecorder()
   110  			token := mock.CreatePolicyAndToken(t, state, 1005, "invalid", mock.NodePolicy(acl.PolicyWrite))
   111  			setToken(req, token)
   112  			_, err := s.Server.AgentSelfRequest(respW, req)
   113  			require.NotNil(err)
   114  			require.Equal(err.Error(), structs.ErrPermissionDenied.Error())
   115  		}
   116  
   117  		// Try request with a valid token
   118  		{
   119  			respW := httptest.NewRecorder()
   120  			token := mock.CreatePolicyAndToken(t, state, 1007, "valid", mock.AgentPolicy(acl.PolicyWrite))
   121  			setToken(req, token)
   122  			obj, err := s.Server.AgentSelfRequest(respW, req)
   123  			require.Nil(err)
   124  
   125  			self := obj.(agentSelf)
   126  			require.NotNil(self.Config)
   127  			require.NotNil(self.Stats)
   128  		}
   129  
   130  		// Try request with a root token
   131  		{
   132  			respW := httptest.NewRecorder()
   133  			setToken(req, s.RootToken)
   134  			obj, err := s.Server.AgentSelfRequest(respW, req)
   135  			require.Nil(err)
   136  
   137  			self := obj.(agentSelf)
   138  			require.NotNil(self.Config)
   139  			require.NotNil(self.Stats)
   140  		}
   141  	})
   142  }
   143  
   144  func TestHTTP_AgentJoin(t *testing.T) {
   145  	t.Parallel()
   146  	httpTest(t, nil, func(s *TestAgent) {
   147  		// Determine the join address
   148  		member := s.Agent.Server().LocalMember()
   149  		addr := fmt.Sprintf("%s:%d", member.Addr, member.Port)
   150  
   151  		// Make the HTTP request
   152  		req, err := http.NewRequest("PUT",
   153  			fmt.Sprintf("/v1/agent/join?address=%s&address=%s", addr, addr), nil)
   154  		if err != nil {
   155  			t.Fatalf("err: %v", err)
   156  		}
   157  		respW := httptest.NewRecorder()
   158  
   159  		// Make the request
   160  		obj, err := s.Server.AgentJoinRequest(respW, req)
   161  		if err != nil {
   162  			t.Fatalf("err: %v", err)
   163  		}
   164  
   165  		// Check the job
   166  		join := obj.(joinResult)
   167  		if join.NumJoined != 2 {
   168  			t.Fatalf("bad: %#v", join)
   169  		}
   170  		if join.Error != "" {
   171  			t.Fatalf("bad: %#v", join)
   172  		}
   173  	})
   174  }
   175  
   176  func TestHTTP_AgentMembers(t *testing.T) {
   177  	t.Parallel()
   178  	httpTest(t, nil, func(s *TestAgent) {
   179  		// Make the HTTP request
   180  		req, err := http.NewRequest("GET", "/v1/agent/members", nil)
   181  		if err != nil {
   182  			t.Fatalf("err: %v", err)
   183  		}
   184  		respW := httptest.NewRecorder()
   185  
   186  		// Make the request
   187  		obj, err := s.Server.AgentMembersRequest(respW, req)
   188  		if err != nil {
   189  			t.Fatalf("err: %v", err)
   190  		}
   191  
   192  		// Check the job
   193  		members := obj.(structs.ServerMembersResponse)
   194  		if len(members.Members) != 1 {
   195  			t.Fatalf("bad: %#v", members.Members)
   196  		}
   197  	})
   198  }
   199  
   200  func TestHTTP_AgentMembers_ACL(t *testing.T) {
   201  	t.Parallel()
   202  	require := require.New(t)
   203  
   204  	httpACLTest(t, nil, func(s *TestAgent) {
   205  		state := s.Agent.server.State()
   206  
   207  		// Make the HTTP request
   208  		req, err := http.NewRequest("GET", "/v1/agent/members", nil)
   209  		require.Nil(err)
   210  
   211  		// Try request without a token and expect failure
   212  		{
   213  			respW := httptest.NewRecorder()
   214  			_, err := s.Server.AgentMembersRequest(respW, req)
   215  			require.NotNil(err)
   216  			require.Equal(err.Error(), structs.ErrPermissionDenied.Error())
   217  		}
   218  
   219  		// Try request with an invalid token and expect failure
   220  		{
   221  			respW := httptest.NewRecorder()
   222  			token := mock.CreatePolicyAndToken(t, state, 1005, "invalid", mock.AgentPolicy(acl.PolicyWrite))
   223  			setToken(req, token)
   224  			_, err := s.Server.AgentMembersRequest(respW, req)
   225  			require.NotNil(err)
   226  			require.Equal(err.Error(), structs.ErrPermissionDenied.Error())
   227  		}
   228  
   229  		// Try request with a valid token
   230  		{
   231  			respW := httptest.NewRecorder()
   232  			token := mock.CreatePolicyAndToken(t, state, 1007, "valid", mock.NodePolicy(acl.PolicyRead))
   233  			setToken(req, token)
   234  			obj, err := s.Server.AgentMembersRequest(respW, req)
   235  			require.Nil(err)
   236  
   237  			members := obj.(structs.ServerMembersResponse)
   238  			require.Len(members.Members, 1)
   239  		}
   240  
   241  		// Try request with a root token
   242  		{
   243  			respW := httptest.NewRecorder()
   244  			setToken(req, s.RootToken)
   245  			obj, err := s.Server.AgentMembersRequest(respW, req)
   246  			require.Nil(err)
   247  
   248  			members := obj.(structs.ServerMembersResponse)
   249  			require.Len(members.Members, 1)
   250  		}
   251  	})
   252  }
   253  
   254  func TestHTTP_AgentMonitor(t *testing.T) {
   255  	t.Parallel()
   256  
   257  	httpTest(t, nil, func(s *TestAgent) {
   258  		// invalid log_json
   259  		{
   260  			req, err := http.NewRequest("GET", "/v1/agent/monitor?log_json=no", nil)
   261  			require.Nil(t, err)
   262  			resp := newClosableRecorder()
   263  
   264  			// Make the request
   265  			_, err = s.Server.AgentMonitor(resp, req)
   266  			if err.(HTTPCodedError).Code() != 400 {
   267  				t.Fatalf("expected 400 response, got: %v", resp.Code)
   268  			}
   269  		}
   270  
   271  		// unknown log_level
   272  		{
   273  			req, err := http.NewRequest("GET", "/v1/agent/monitor?log_level=unknown", nil)
   274  			require.Nil(t, err)
   275  			resp := newClosableRecorder()
   276  
   277  			// Make the request
   278  			_, err = s.Server.AgentMonitor(resp, req)
   279  			if err.(HTTPCodedError).Code() != 400 {
   280  				t.Fatalf("expected 400 response, got: %v", resp.Code)
   281  			}
   282  		}
   283  
   284  		// check for a specific log
   285  		{
   286  			req, err := http.NewRequest("GET", "/v1/agent/monitor?log_level=warn", nil)
   287  			require.Nil(t, err)
   288  			resp := newClosableRecorder()
   289  			defer resp.Close()
   290  
   291  			go func() {
   292  				_, err = s.Server.AgentMonitor(resp, req)
   293  				require.NoError(t, err)
   294  			}()
   295  
   296  			// send the same log until monitor sink is set up
   297  			maxLogAttempts := 10
   298  			tried := 0
   299  			testutil.WaitForResult(func() (bool, error) {
   300  				if tried < maxLogAttempts {
   301  					s.Server.logger.Warn("log that should be sent")
   302  					tried++
   303  				}
   304  
   305  				got := resp.Body.String()
   306  				want := `{"Data":"`
   307  				if strings.Contains(got, want) {
   308  					return true, nil
   309  				}
   310  
   311  				return false, fmt.Errorf("missing expected log, got: %v, want: %v", got, want)
   312  			}, func(err error) {
   313  				require.Fail(t, err.Error())
   314  			})
   315  		}
   316  
   317  		// plain param set to true
   318  		{
   319  			req, err := http.NewRequest("GET", "/v1/agent/monitor?log_level=debug&plain=true", nil)
   320  			require.Nil(t, err)
   321  			resp := newClosableRecorder()
   322  			defer resp.Close()
   323  
   324  			go func() {
   325  				_, err = s.Server.AgentMonitor(resp, req)
   326  				require.NoError(t, err)
   327  			}()
   328  
   329  			// send the same log until monitor sink is set up
   330  			maxLogAttempts := 10
   331  			tried := 0
   332  			testutil.WaitForResult(func() (bool, error) {
   333  				if tried < maxLogAttempts {
   334  					s.Server.logger.Debug("log that should be sent")
   335  					tried++
   336  				}
   337  
   338  				got := resp.Body.String()
   339  				want := `[DEBUG] http: log that should be sent`
   340  				if strings.Contains(got, want) {
   341  					return true, nil
   342  				}
   343  
   344  				return false, fmt.Errorf("missing expected log, got: %v, want: %v", got, want)
   345  			}, func(err error) {
   346  				require.Fail(t, err.Error())
   347  			})
   348  		}
   349  
   350  		// stream logs for a given node
   351  		{
   352  			req, err := http.NewRequest("GET", "/v1/agent/monitor?log_level=warn&node_id="+s.client.NodeID(), nil)
   353  			require.Nil(t, err)
   354  			resp := newClosableRecorder()
   355  			defer resp.Close()
   356  
   357  			go func() {
   358  				_, err = s.Server.AgentMonitor(resp, req)
   359  				require.NoError(t, err)
   360  			}()
   361  
   362  			// send the same log until monitor sink is set up
   363  			maxLogAttempts := 10
   364  			tried := 0
   365  			out := ""
   366  			testutil.WaitForResult(func() (bool, error) {
   367  				if tried < maxLogAttempts {
   368  					s.Server.logger.Debug("log that should not be sent")
   369  					s.Server.logger.Warn("log that should be sent")
   370  					tried++
   371  				}
   372  				output, err := ioutil.ReadAll(resp.Body)
   373  				if err != nil {
   374  					return false, err
   375  				}
   376  
   377  				out += string(output)
   378  				want := `{"Data":"`
   379  				if strings.Contains(out, want) {
   380  					return true, nil
   381  				}
   382  
   383  				return false, fmt.Errorf("missing expected log, got: %v, want: %v", out, want)
   384  			}, func(err error) {
   385  				require.Fail(t, err.Error())
   386  			})
   387  		}
   388  	})
   389  }
   390  
   391  type closableRecorder struct {
   392  	*httptest.ResponseRecorder
   393  	closer chan bool
   394  }
   395  
   396  func newClosableRecorder() *closableRecorder {
   397  	r := httptest.NewRecorder()
   398  	closer := make(chan bool)
   399  	return &closableRecorder{r, closer}
   400  }
   401  
   402  func (r *closableRecorder) Close() {
   403  	close(r.closer)
   404  }
   405  
   406  func (r *closableRecorder) CloseNotify() <-chan bool {
   407  	return r.closer
   408  }
   409  
   410  func TestHTTP_AgentForceLeave(t *testing.T) {
   411  	t.Parallel()
   412  	httpTest(t, nil, func(s *TestAgent) {
   413  		// Make the HTTP request
   414  		req, err := http.NewRequest("PUT", "/v1/agent/force-leave?node=foo", nil)
   415  		if err != nil {
   416  			t.Fatalf("err: %v", err)
   417  		}
   418  		respW := httptest.NewRecorder()
   419  
   420  		// Make the request
   421  		_, err = s.Server.AgentForceLeaveRequest(respW, req)
   422  		if err != nil {
   423  			t.Fatalf("err: %v", err)
   424  		}
   425  	})
   426  }
   427  
   428  func TestHTTP_AgentForceLeave_ACL(t *testing.T) {
   429  	t.Parallel()
   430  	require := require.New(t)
   431  
   432  	httpACLTest(t, nil, func(s *TestAgent) {
   433  		state := s.Agent.server.State()
   434  
   435  		// Make the HTTP request
   436  		req, err := http.NewRequest("PUT", "/v1/agent/force-leave?node=foo", nil)
   437  		require.Nil(err)
   438  
   439  		// Try request without a token and expect failure
   440  		{
   441  			respW := httptest.NewRecorder()
   442  			_, err := s.Server.AgentForceLeaveRequest(respW, req)
   443  			require.NotNil(err)
   444  			require.Equal(err.Error(), structs.ErrPermissionDenied.Error())
   445  		}
   446  
   447  		// Try request with an invalid token and expect failure
   448  		{
   449  			respW := httptest.NewRecorder()
   450  			token := mock.CreatePolicyAndToken(t, state, 1005, "invalid", mock.NodePolicy(acl.PolicyRead))
   451  			setToken(req, token)
   452  			_, err := s.Server.AgentForceLeaveRequest(respW, req)
   453  			require.NotNil(err)
   454  			require.Equal(err.Error(), structs.ErrPermissionDenied.Error())
   455  		}
   456  
   457  		// Try request with a valid token
   458  		{
   459  			respW := httptest.NewRecorder()
   460  			token := mock.CreatePolicyAndToken(t, state, 1007, "valid", mock.AgentPolicy(acl.PolicyWrite))
   461  			setToken(req, token)
   462  			_, err := s.Server.AgentForceLeaveRequest(respW, req)
   463  			require.Nil(err)
   464  			require.Equal(http.StatusOK, respW.Code)
   465  		}
   466  
   467  		// Try request with a root token
   468  		{
   469  			respW := httptest.NewRecorder()
   470  			setToken(req, s.RootToken)
   471  			_, err := s.Server.AgentForceLeaveRequest(respW, req)
   472  			require.Nil(err)
   473  			require.Equal(http.StatusOK, respW.Code)
   474  		}
   475  	})
   476  }
   477  
   478  func TestHTTP_AgentSetServers(t *testing.T) {
   479  	t.Parallel()
   480  	require := require.New(t)
   481  	httpTest(t, nil, func(s *TestAgent) {
   482  		addr := s.Config.AdvertiseAddrs.RPC
   483  		testutil.WaitForResult(func() (bool, error) {
   484  			conn, err := net.DialTimeout("tcp", addr, 100*time.Millisecond)
   485  			if err != nil {
   486  				return false, err
   487  			}
   488  			defer conn.Close()
   489  
   490  			// Write the Consul RPC byte to set the mode
   491  			if _, err := conn.Write([]byte{byte(pool.RpcNomad)}); err != nil {
   492  				return false, err
   493  			}
   494  
   495  			codec := pool.NewClientCodec(conn)
   496  			args := &structs.GenericRequest{}
   497  			var leader string
   498  			err = msgpackrpc.CallWithCodec(codec, "Status.Leader", args, &leader)
   499  			return leader != "", err
   500  		}, func(err error) {
   501  			t.Fatalf("failed to find leader: %v", err)
   502  		})
   503  
   504  		// Create the request
   505  		req, err := http.NewRequest("PUT", "/v1/agent/servers", nil)
   506  		require.Nil(err)
   507  
   508  		// Send the request
   509  		respW := httptest.NewRecorder()
   510  		_, err = s.Server.AgentServersRequest(respW, req)
   511  		require.NotNil(err)
   512  		require.Contains(err.Error(), "missing server address")
   513  
   514  		// Create a valid request
   515  		req, err = http.NewRequest("PUT", "/v1/agent/servers?address=127.0.0.1%3A4647&address=127.0.0.2%3A4647&address=127.0.0.3%3A4647", nil)
   516  		require.Nil(err)
   517  
   518  		// Send the request which should fail
   519  		respW = httptest.NewRecorder()
   520  		_, err = s.Server.AgentServersRequest(respW, req)
   521  		require.NotNil(err)
   522  
   523  		// Retrieve the servers again
   524  		req, err = http.NewRequest("GET", "/v1/agent/servers", nil)
   525  		require.Nil(err)
   526  		respW = httptest.NewRecorder()
   527  
   528  		// Make the request and check the result
   529  		expected := []string{
   530  			s.GetConfig().AdvertiseAddrs.RPC,
   531  		}
   532  		out, err := s.Server.AgentServersRequest(respW, req)
   533  		require.Nil(err)
   534  		servers := out.([]string)
   535  		require.Len(servers, len(expected))
   536  		require.Equal(expected, servers)
   537  	})
   538  }
   539  
   540  func TestHTTP_AgentSetServers_ACL(t *testing.T) {
   541  	t.Parallel()
   542  	require := require.New(t)
   543  
   544  	httpACLTest(t, nil, func(s *TestAgent) {
   545  		state := s.Agent.server.State()
   546  		addr := s.Config.AdvertiseAddrs.RPC
   547  		testutil.WaitForResult(func() (bool, error) {
   548  			conn, err := net.DialTimeout("tcp", addr, 100*time.Millisecond)
   549  			if err != nil {
   550  				return false, err
   551  			}
   552  			defer conn.Close()
   553  
   554  			// Write the Consul RPC byte to set the mode
   555  			if _, err := conn.Write([]byte{byte(pool.RpcNomad)}); err != nil {
   556  				return false, err
   557  			}
   558  
   559  			codec := pool.NewClientCodec(conn)
   560  			args := &structs.GenericRequest{}
   561  			var leader string
   562  			err = msgpackrpc.CallWithCodec(codec, "Status.Leader", args, &leader)
   563  			return leader != "", err
   564  		}, func(err error) {
   565  			t.Fatalf("failed to find leader: %v", err)
   566  		})
   567  
   568  		// Make the HTTP request
   569  		path := fmt.Sprintf("/v1/agent/servers?address=%s", url.QueryEscape(s.GetConfig().AdvertiseAddrs.RPC))
   570  		req, err := http.NewRequest("PUT", path, nil)
   571  		require.Nil(err)
   572  
   573  		// Try request without a token and expect failure
   574  		{
   575  			respW := httptest.NewRecorder()
   576  			_, err := s.Server.AgentServersRequest(respW, req)
   577  			require.NotNil(err)
   578  			require.Equal(err.Error(), structs.ErrPermissionDenied.Error())
   579  		}
   580  
   581  		// Try request with an invalid token and expect failure
   582  		{
   583  			respW := httptest.NewRecorder()
   584  			token := mock.CreatePolicyAndToken(t, state, 1005, "invalid", mock.NodePolicy(acl.PolicyRead))
   585  			setToken(req, token)
   586  			_, err := s.Server.AgentServersRequest(respW, req)
   587  			require.NotNil(err)
   588  			require.Equal(err.Error(), structs.ErrPermissionDenied.Error())
   589  		}
   590  
   591  		// Try request with a valid token
   592  		{
   593  			respW := httptest.NewRecorder()
   594  			token := mock.CreatePolicyAndToken(t, state, 1007, "valid", mock.AgentPolicy(acl.PolicyWrite))
   595  			setToken(req, token)
   596  			_, err := s.Server.AgentServersRequest(respW, req)
   597  			require.Nil(err)
   598  			require.Equal(http.StatusOK, respW.Code)
   599  		}
   600  
   601  		// Try request with a root token
   602  		{
   603  			respW := httptest.NewRecorder()
   604  			setToken(req, s.RootToken)
   605  			_, err := s.Server.AgentServersRequest(respW, req)
   606  			require.Nil(err)
   607  			require.Equal(http.StatusOK, respW.Code)
   608  		}
   609  	})
   610  }
   611  
   612  func TestHTTP_AgentListServers_ACL(t *testing.T) {
   613  	t.Parallel()
   614  	require := require.New(t)
   615  
   616  	httpACLTest(t, nil, func(s *TestAgent) {
   617  		state := s.Agent.server.State()
   618  
   619  		// Create list request
   620  		req, err := http.NewRequest("GET", "/v1/agent/servers", nil)
   621  		require.Nil(err)
   622  
   623  		expected := []string{
   624  			s.GetConfig().AdvertiseAddrs.RPC,
   625  		}
   626  
   627  		// Try request without a token and expect failure
   628  		{
   629  			respW := httptest.NewRecorder()
   630  			_, err := s.Server.AgentServersRequest(respW, req)
   631  			require.NotNil(err)
   632  			require.Equal(err.Error(), structs.ErrPermissionDenied.Error())
   633  		}
   634  
   635  		// Try request with an invalid token and expect failure
   636  		{
   637  			respW := httptest.NewRecorder()
   638  			token := mock.CreatePolicyAndToken(t, state, 1005, "invalid", mock.NodePolicy(acl.PolicyRead))
   639  			setToken(req, token)
   640  			_, err := s.Server.AgentServersRequest(respW, req)
   641  			require.NotNil(err)
   642  			require.Equal(err.Error(), structs.ErrPermissionDenied.Error())
   643  		}
   644  
   645  		// Wait for client to have a server
   646  		testutil.WaitForResult(func() (bool, error) {
   647  			return len(s.client.GetServers()) != 0, fmt.Errorf("no servers")
   648  		}, func(err error) {
   649  			t.Fatal(err)
   650  		})
   651  
   652  		// Try request with a valid token
   653  		{
   654  			respW := httptest.NewRecorder()
   655  			token := mock.CreatePolicyAndToken(t, state, 1007, "valid", mock.AgentPolicy(acl.PolicyRead))
   656  			setToken(req, token)
   657  			out, err := s.Server.AgentServersRequest(respW, req)
   658  			require.Nil(err)
   659  			servers := out.([]string)
   660  			require.Len(servers, len(expected))
   661  			require.Equal(expected, servers)
   662  		}
   663  
   664  		// Try request with a root token
   665  		{
   666  			respW := httptest.NewRecorder()
   667  			setToken(req, s.RootToken)
   668  			out, err := s.Server.AgentServersRequest(respW, req)
   669  			require.Nil(err)
   670  			servers := out.([]string)
   671  			require.Len(servers, len(expected))
   672  			require.Equal(expected, servers)
   673  		}
   674  	})
   675  }
   676  
   677  func TestHTTP_AgentListKeys(t *testing.T) {
   678  	t.Parallel()
   679  
   680  	key1 := "HS5lJ+XuTlYKWaeGYyG+/A=="
   681  
   682  	httpTest(t, func(c *Config) {
   683  		c.Server.EncryptKey = key1
   684  	}, func(s *TestAgent) {
   685  		req, err := http.NewRequest("GET", "/v1/agent/keyring/list", nil)
   686  		if err != nil {
   687  			t.Fatalf("err: %s", err)
   688  		}
   689  		respW := httptest.NewRecorder()
   690  
   691  		out, err := s.Server.KeyringOperationRequest(respW, req)
   692  		require.Nil(t, err)
   693  		kresp := out.(structs.KeyringResponse)
   694  		require.Len(t, kresp.Keys, 1)
   695  	})
   696  }
   697  
   698  func TestHTTP_AgentListKeys_ACL(t *testing.T) {
   699  	t.Parallel()
   700  	require := require.New(t)
   701  
   702  	key1 := "HS5lJ+XuTlYKWaeGYyG+/A=="
   703  
   704  	cb := func(c *Config) {
   705  		c.Server.EncryptKey = key1
   706  	}
   707  
   708  	httpACLTest(t, cb, func(s *TestAgent) {
   709  		state := s.Agent.server.State()
   710  
   711  		// Make the HTTP request
   712  		req, err := http.NewRequest("GET", "/v1/agent/keyring/list", nil)
   713  		require.Nil(err)
   714  
   715  		// Try request without a token and expect failure
   716  		{
   717  			respW := httptest.NewRecorder()
   718  			_, err := s.Server.KeyringOperationRequest(respW, req)
   719  			require.NotNil(err)
   720  			require.Equal(err.Error(), structs.ErrPermissionDenied.Error())
   721  		}
   722  
   723  		// Try request with an invalid token and expect failure
   724  		{
   725  			respW := httptest.NewRecorder()
   726  			token := mock.CreatePolicyAndToken(t, state, 1005, "invalid", mock.AgentPolicy(acl.PolicyRead))
   727  			setToken(req, token)
   728  			_, err := s.Server.KeyringOperationRequest(respW, req)
   729  			require.NotNil(err)
   730  			require.Equal(err.Error(), structs.ErrPermissionDenied.Error())
   731  		}
   732  
   733  		// Try request with a valid token
   734  		{
   735  			respW := httptest.NewRecorder()
   736  			token := mock.CreatePolicyAndToken(t, state, 1007, "valid", mock.AgentPolicy(acl.PolicyWrite))
   737  			setToken(req, token)
   738  			out, err := s.Server.KeyringOperationRequest(respW, req)
   739  			require.Nil(err)
   740  			kresp := out.(structs.KeyringResponse)
   741  			require.Len(kresp.Keys, 1)
   742  			require.Contains(kresp.Keys, key1)
   743  		}
   744  
   745  		// Try request with a root token
   746  		{
   747  			respW := httptest.NewRecorder()
   748  			setToken(req, s.RootToken)
   749  			out, err := s.Server.KeyringOperationRequest(respW, req)
   750  			require.Nil(err)
   751  			kresp := out.(structs.KeyringResponse)
   752  			require.Len(kresp.Keys, 1)
   753  			require.Contains(kresp.Keys, key1)
   754  		}
   755  	})
   756  }
   757  
   758  func TestHTTP_AgentInstallKey(t *testing.T) {
   759  	t.Parallel()
   760  
   761  	key1 := "HS5lJ+XuTlYKWaeGYyG+/A=="
   762  	key2 := "wH1Bn9hlJ0emgWB1JttVRA=="
   763  
   764  	httpTest(t, func(c *Config) {
   765  		c.Server.EncryptKey = key1
   766  	}, func(s *TestAgent) {
   767  		b, err := json.Marshal(&structs.KeyringRequest{Key: key2})
   768  		if err != nil {
   769  			t.Fatalf("err: %v", err)
   770  		}
   771  		req, err := http.NewRequest("GET", "/v1/agent/keyring/install", bytes.NewReader(b))
   772  		if err != nil {
   773  			t.Fatalf("err: %s", err)
   774  		}
   775  		respW := httptest.NewRecorder()
   776  
   777  		_, err = s.Server.KeyringOperationRequest(respW, req)
   778  		if err != nil {
   779  			t.Fatalf("err: %s", err)
   780  		}
   781  		req, err = http.NewRequest("GET", "/v1/agent/keyring/list", bytes.NewReader(b))
   782  		if err != nil {
   783  			t.Fatalf("err: %s", err)
   784  		}
   785  		respW = httptest.NewRecorder()
   786  
   787  		out, err := s.Server.KeyringOperationRequest(respW, req)
   788  		if err != nil {
   789  			t.Fatalf("err: %s", err)
   790  		}
   791  		kresp := out.(structs.KeyringResponse)
   792  		if len(kresp.Keys) != 2 {
   793  			t.Fatalf("bad: %v", kresp)
   794  		}
   795  	})
   796  }
   797  
   798  func TestHTTP_AgentRemoveKey(t *testing.T) {
   799  	t.Parallel()
   800  
   801  	key1 := "HS5lJ+XuTlYKWaeGYyG+/A=="
   802  	key2 := "wH1Bn9hlJ0emgWB1JttVRA=="
   803  
   804  	httpTest(t, func(c *Config) {
   805  		c.Server.EncryptKey = key1
   806  	}, func(s *TestAgent) {
   807  		b, err := json.Marshal(&structs.KeyringRequest{Key: key2})
   808  		if err != nil {
   809  			t.Fatalf("err: %v", err)
   810  		}
   811  
   812  		req, err := http.NewRequest("GET", "/v1/agent/keyring/install", bytes.NewReader(b))
   813  		if err != nil {
   814  			t.Fatalf("err: %s", err)
   815  		}
   816  		respW := httptest.NewRecorder()
   817  		_, err = s.Server.KeyringOperationRequest(respW, req)
   818  		if err != nil {
   819  			t.Fatalf("err: %s", err)
   820  		}
   821  
   822  		req, err = http.NewRequest("GET", "/v1/agent/keyring/remove", bytes.NewReader(b))
   823  		if err != nil {
   824  			t.Fatalf("err: %s", err)
   825  		}
   826  		respW = httptest.NewRecorder()
   827  		if _, err = s.Server.KeyringOperationRequest(respW, req); err != nil {
   828  			t.Fatalf("err: %s", err)
   829  		}
   830  
   831  		req, err = http.NewRequest("GET", "/v1/agent/keyring/list", nil)
   832  		if err != nil {
   833  			t.Fatalf("err: %s", err)
   834  		}
   835  		respW = httptest.NewRecorder()
   836  		out, err := s.Server.KeyringOperationRequest(respW, req)
   837  		if err != nil {
   838  			t.Fatalf("err: %s", err)
   839  		}
   840  		kresp := out.(structs.KeyringResponse)
   841  		if len(kresp.Keys) != 1 {
   842  			t.Fatalf("bad: %v", kresp)
   843  		}
   844  	})
   845  }
   846  
   847  func TestHTTP_AgentHealth_Ok(t *testing.T) {
   848  	t.Parallel()
   849  	require := require.New(t)
   850  
   851  	// Enable ACLs to ensure they're not enforced
   852  	httpACLTest(t, nil, func(s *TestAgent) {
   853  		// No ?type=
   854  		{
   855  			req, err := http.NewRequest("GET", "/v1/agent/health", nil)
   856  			require.Nil(err)
   857  
   858  			respW := httptest.NewRecorder()
   859  			healthI, err := s.Server.HealthRequest(respW, req)
   860  			require.Nil(err)
   861  			require.Equal(http.StatusOK, respW.Code)
   862  			require.NotNil(healthI)
   863  			health := healthI.(*healthResponse)
   864  			require.NotNil(health.Client)
   865  			require.True(health.Client.Ok)
   866  			require.Equal("ok", health.Client.Message)
   867  			require.NotNil(health.Server)
   868  			require.True(health.Server.Ok)
   869  			require.Equal("ok", health.Server.Message)
   870  		}
   871  
   872  		// type=client
   873  		{
   874  			req, err := http.NewRequest("GET", "/v1/agent/health?type=client", nil)
   875  			require.Nil(err)
   876  
   877  			respW := httptest.NewRecorder()
   878  			healthI, err := s.Server.HealthRequest(respW, req)
   879  			require.Nil(err)
   880  			require.Equal(http.StatusOK, respW.Code)
   881  			require.NotNil(healthI)
   882  			health := healthI.(*healthResponse)
   883  			require.NotNil(health.Client)
   884  			require.True(health.Client.Ok)
   885  			require.Equal("ok", health.Client.Message)
   886  			require.Nil(health.Server)
   887  		}
   888  
   889  		// type=server
   890  		{
   891  			req, err := http.NewRequest("GET", "/v1/agent/health?type=server", nil)
   892  			require.Nil(err)
   893  
   894  			respW := httptest.NewRecorder()
   895  			healthI, err := s.Server.HealthRequest(respW, req)
   896  			require.Nil(err)
   897  			require.Equal(http.StatusOK, respW.Code)
   898  			require.NotNil(healthI)
   899  			health := healthI.(*healthResponse)
   900  			require.NotNil(health.Server)
   901  			require.True(health.Server.Ok)
   902  			require.Equal("ok", health.Server.Message)
   903  			require.Nil(health.Client)
   904  		}
   905  
   906  		// type=client&type=server
   907  		{
   908  			req, err := http.NewRequest("GET", "/v1/agent/health?type=client&type=server", nil)
   909  			require.Nil(err)
   910  
   911  			respW := httptest.NewRecorder()
   912  			healthI, err := s.Server.HealthRequest(respW, req)
   913  			require.Nil(err)
   914  			require.Equal(http.StatusOK, respW.Code)
   915  			require.NotNil(healthI)
   916  			health := healthI.(*healthResponse)
   917  			require.NotNil(health.Client)
   918  			require.True(health.Client.Ok)
   919  			require.Equal("ok", health.Client.Message)
   920  			require.NotNil(health.Server)
   921  			require.True(health.Server.Ok)
   922  			require.Equal("ok", health.Server.Message)
   923  		}
   924  	})
   925  }
   926  
   927  func TestHTTP_AgentHealth_BadServer(t *testing.T) {
   928  	t.Parallel()
   929  	require := require.New(t)
   930  
   931  	// Enable ACLs to ensure they're not enforced
   932  	httpACLTest(t, nil, func(s *TestAgent) {
   933  
   934  		// Set s.Agent.server=nil to make server unhealthy if requested
   935  		s.Agent.server = nil
   936  
   937  		// No ?type= means server is just skipped
   938  		{
   939  			req, err := http.NewRequest("GET", "/v1/agent/health", nil)
   940  			require.Nil(err)
   941  
   942  			respW := httptest.NewRecorder()
   943  			healthI, err := s.Server.HealthRequest(respW, req)
   944  			require.Nil(err)
   945  			require.Equal(http.StatusOK, respW.Code)
   946  			require.NotNil(healthI)
   947  			health := healthI.(*healthResponse)
   948  			require.NotNil(health.Client)
   949  			require.True(health.Client.Ok)
   950  			require.Equal("ok", health.Client.Message)
   951  			require.Nil(health.Server)
   952  		}
   953  
   954  		// type=server means server is considered unhealthy
   955  		{
   956  			req, err := http.NewRequest("GET", "/v1/agent/health?type=server", nil)
   957  			require.Nil(err)
   958  
   959  			respW := httptest.NewRecorder()
   960  			_, err = s.Server.HealthRequest(respW, req)
   961  			require.NotNil(err)
   962  			httpErr, ok := err.(HTTPCodedError)
   963  			require.True(ok)
   964  			require.Equal(500, httpErr.Code())
   965  			require.Equal(`{"server":{"ok":false,"message":"server not enabled"}}`, err.Error())
   966  		}
   967  	})
   968  }
   969  
   970  func TestHTTP_AgentHealth_BadClient(t *testing.T) {
   971  	t.Parallel()
   972  	require := require.New(t)
   973  
   974  	// Enable ACLs to ensure they're not enforced
   975  	httpACLTest(t, nil, func(s *TestAgent) {
   976  
   977  		// Set s.Agent.client=nil to make server unhealthy if requested
   978  		s.Agent.client = nil
   979  
   980  		// No ?type= means client is just skipped
   981  		{
   982  			req, err := http.NewRequest("GET", "/v1/agent/health", nil)
   983  			require.Nil(err)
   984  
   985  			respW := httptest.NewRecorder()
   986  			healthI, err := s.Server.HealthRequest(respW, req)
   987  			require.Nil(err)
   988  			require.Equal(http.StatusOK, respW.Code)
   989  			require.NotNil(healthI)
   990  			health := healthI.(*healthResponse)
   991  			require.NotNil(health.Server)
   992  			require.True(health.Server.Ok)
   993  			require.Equal("ok", health.Server.Message)
   994  			require.Nil(health.Client)
   995  		}
   996  
   997  		// type=client means client is considered unhealthy
   998  		{
   999  			req, err := http.NewRequest("GET", "/v1/agent/health?type=client", nil)
  1000  			require.Nil(err)
  1001  
  1002  			respW := httptest.NewRecorder()
  1003  			_, err = s.Server.HealthRequest(respW, req)
  1004  			require.NotNil(err)
  1005  			httpErr, ok := err.(HTTPCodedError)
  1006  			require.True(ok)
  1007  			require.Equal(500, httpErr.Code())
  1008  			require.Equal(`{"client":{"ok":false,"message":"client not enabled"}}`, err.Error())
  1009  		}
  1010  	})
  1011  }