github.com/Iqoqo/consul@v1.4.5/agent/operator_endpoint_test.go (about)

     1  package agent
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"net/http"
     7  	"net/http/httptest"
     8  	"strings"
     9  	"testing"
    10  
    11  	"github.com/hashicorp/consul/testrpc"
    12  
    13  	"github.com/hashicorp/consul/agent/consul/autopilot"
    14  	"github.com/hashicorp/consul/agent/structs"
    15  	"github.com/hashicorp/consul/api"
    16  	"github.com/hashicorp/consul/testutil/retry"
    17  )
    18  
    19  func TestOperator_RaftConfiguration(t *testing.T) {
    20  	t.Parallel()
    21  	a := NewTestAgent(t, t.Name(), "")
    22  	defer a.Shutdown()
    23  
    24  	body := bytes.NewBuffer(nil)
    25  	req, _ := http.NewRequest("GET", "/v1/operator/raft/configuration", body)
    26  	resp := httptest.NewRecorder()
    27  	obj, err := a.srv.OperatorRaftConfiguration(resp, req)
    28  	if err != nil {
    29  		t.Fatalf("err: %v", err)
    30  	}
    31  	if resp.Code != 200 {
    32  		t.Fatalf("bad code: %d", resp.Code)
    33  	}
    34  	out, ok := obj.(structs.RaftConfigurationResponse)
    35  	if !ok {
    36  		t.Fatalf("unexpected: %T", obj)
    37  	}
    38  	if len(out.Servers) != 1 ||
    39  		!out.Servers[0].Leader ||
    40  		!out.Servers[0].Voter {
    41  		t.Fatalf("bad: %v", out)
    42  	}
    43  }
    44  
    45  func TestOperator_RaftPeer(t *testing.T) {
    46  	t.Parallel()
    47  	t.Run("", func(t *testing.T) {
    48  		a := NewTestAgent(t, t.Name(), "")
    49  		defer a.Shutdown()
    50  
    51  		body := bytes.NewBuffer(nil)
    52  		req, _ := http.NewRequest("DELETE", "/v1/operator/raft/peer?address=nope", body)
    53  		// If we get this error, it proves we sent the address all the
    54  		// way through.
    55  		resp := httptest.NewRecorder()
    56  		_, err := a.srv.OperatorRaftPeer(resp, req)
    57  		if err == nil || !strings.Contains(err.Error(),
    58  			"address \"nope\" was not found in the Raft configuration") {
    59  			t.Fatalf("err: %v", err)
    60  		}
    61  	})
    62  
    63  	t.Run("", func(t *testing.T) {
    64  		a := NewTestAgent(t, t.Name(), "")
    65  		defer a.Shutdown()
    66  
    67  		body := bytes.NewBuffer(nil)
    68  		req, _ := http.NewRequest("DELETE", "/v1/operator/raft/peer?id=nope", body)
    69  		// If we get this error, it proves we sent the ID all the
    70  		// way through.
    71  		resp := httptest.NewRecorder()
    72  		_, err := a.srv.OperatorRaftPeer(resp, req)
    73  		if err == nil || !strings.Contains(err.Error(),
    74  			"id \"nope\" was not found in the Raft configuration") {
    75  			t.Fatalf("err: %v", err)
    76  		}
    77  	})
    78  }
    79  
    80  func TestOperator_KeyringInstall(t *testing.T) {
    81  	t.Parallel()
    82  	oldKey := "H3/9gBxcKKRf45CaI2DlRg=="
    83  	newKey := "z90lFx3sZZLtTOkutXcwYg=="
    84  	a := NewTestAgent(t, t.Name(), `
    85  		encrypt = "`+oldKey+`"
    86  	`)
    87  	defer a.Shutdown()
    88  
    89  	body := bytes.NewBufferString(fmt.Sprintf("{\"Key\":\"%s\"}", newKey))
    90  	req, _ := http.NewRequest("POST", "/v1/operator/keyring", body)
    91  	resp := httptest.NewRecorder()
    92  	_, err := a.srv.OperatorKeyringEndpoint(resp, req)
    93  	if err != nil {
    94  		t.Fatalf("err: %s", err)
    95  	}
    96  
    97  	listResponse, err := a.ListKeys("", 0)
    98  	if err != nil {
    99  		t.Fatalf("err: %s", err)
   100  	}
   101  	if len(listResponse.Responses) != 2 {
   102  		t.Fatalf("bad: %d", len(listResponse.Responses))
   103  	}
   104  
   105  	for _, response := range listResponse.Responses {
   106  		count, ok := response.Keys[newKey]
   107  		if !ok {
   108  			t.Fatalf("bad: %v", response.Keys)
   109  		}
   110  		if count != response.NumNodes {
   111  			t.Fatalf("bad: %d, %d", count, response.NumNodes)
   112  		}
   113  	}
   114  }
   115  
   116  func TestOperator_KeyringList(t *testing.T) {
   117  	t.Parallel()
   118  	key := "H3/9gBxcKKRf45CaI2DlRg=="
   119  	a := NewTestAgent(t, t.Name(), `
   120  		encrypt = "`+key+`"
   121  	`)
   122  	defer a.Shutdown()
   123  
   124  	req, _ := http.NewRequest("GET", "/v1/operator/keyring", nil)
   125  	resp := httptest.NewRecorder()
   126  	r, err := a.srv.OperatorKeyringEndpoint(resp, req)
   127  	if err != nil {
   128  		t.Fatalf("err: %v", err)
   129  	}
   130  	responses, ok := r.([]*structs.KeyringResponse)
   131  	if !ok {
   132  		t.Fatalf("err: %v", !ok)
   133  	}
   134  
   135  	// Check that we get both a LAN and WAN response, and that they both only
   136  	// contain the original key
   137  	if len(responses) != 2 {
   138  		t.Fatalf("bad: %d", len(responses))
   139  	}
   140  
   141  	// WAN
   142  	if len(responses[0].Keys) != 1 {
   143  		t.Fatalf("bad: %d", len(responses[0].Keys))
   144  	}
   145  	if !responses[0].WAN {
   146  		t.Fatalf("bad: %v", responses[0].WAN)
   147  	}
   148  	if _, ok := responses[0].Keys[key]; !ok {
   149  		t.Fatalf("bad: %v", ok)
   150  	}
   151  
   152  	// LAN
   153  	if len(responses[1].Keys) != 1 {
   154  		t.Fatalf("bad: %d", len(responses[1].Keys))
   155  	}
   156  	if responses[1].WAN {
   157  		t.Fatalf("bad: %v", responses[1].WAN)
   158  	}
   159  	if _, ok := responses[1].Keys[key]; !ok {
   160  		t.Fatalf("bad: %v", ok)
   161  	}
   162  }
   163  
   164  func TestOperator_KeyringRemove(t *testing.T) {
   165  	t.Parallel()
   166  	key := "H3/9gBxcKKRf45CaI2DlRg=="
   167  	tempKey := "z90lFx3sZZLtTOkutXcwYg=="
   168  	a := NewTestAgent(t, t.Name(), `
   169  		encrypt = "`+key+`"
   170  	`)
   171  	defer a.Shutdown()
   172  
   173  	_, err := a.InstallKey(tempKey, "", 0)
   174  	if err != nil {
   175  		t.Fatalf("err: %v", err)
   176  	}
   177  
   178  	// Make sure the temp key is installed
   179  	list, err := a.ListKeys("", 0)
   180  	if err != nil {
   181  		t.Fatalf("err: %v", err)
   182  	}
   183  	responses := list.Responses
   184  	if len(responses) != 2 {
   185  		t.Fatalf("bad: %d", len(responses))
   186  	}
   187  	for _, response := range responses {
   188  		if len(response.Keys) != 2 {
   189  			t.Fatalf("bad: %d", len(response.Keys))
   190  		}
   191  		if _, ok := response.Keys[tempKey]; !ok {
   192  			t.Fatalf("bad: %v", ok)
   193  		}
   194  	}
   195  
   196  	body := bytes.NewBufferString(fmt.Sprintf("{\"Key\":\"%s\"}", tempKey))
   197  	req, _ := http.NewRequest("DELETE", "/v1/operator/keyring", body)
   198  	resp := httptest.NewRecorder()
   199  	if _, err := a.srv.OperatorKeyringEndpoint(resp, req); err != nil {
   200  		t.Fatalf("err: %s", err)
   201  	}
   202  
   203  	// Make sure the temp key has been removed
   204  	list, err = a.ListKeys("", 0)
   205  	if err != nil {
   206  		t.Fatalf("err: %v", err)
   207  	}
   208  	responses = list.Responses
   209  	if len(responses) != 2 {
   210  		t.Fatalf("bad: %d", len(responses))
   211  	}
   212  	for _, response := range responses {
   213  		if len(response.Keys) != 1 {
   214  			t.Fatalf("bad: %d", len(response.Keys))
   215  		}
   216  		if _, ok := response.Keys[tempKey]; ok {
   217  			t.Fatalf("bad: %v", ok)
   218  		}
   219  	}
   220  }
   221  
   222  func TestOperator_KeyringUse(t *testing.T) {
   223  	t.Parallel()
   224  	oldKey := "H3/9gBxcKKRf45CaI2DlRg=="
   225  	newKey := "z90lFx3sZZLtTOkutXcwYg=="
   226  	a := NewTestAgent(t, t.Name(), `
   227  		encrypt = "`+oldKey+`"
   228  	`)
   229  	defer a.Shutdown()
   230  
   231  	if _, err := a.InstallKey(newKey, "", 0); err != nil {
   232  		t.Fatalf("err: %v", err)
   233  	}
   234  
   235  	body := bytes.NewBufferString(fmt.Sprintf("{\"Key\":\"%s\"}", newKey))
   236  	req, _ := http.NewRequest("PUT", "/v1/operator/keyring", body)
   237  	resp := httptest.NewRecorder()
   238  	_, err := a.srv.OperatorKeyringEndpoint(resp, req)
   239  	if err != nil {
   240  		t.Fatalf("err: %s", err)
   241  	}
   242  
   243  	if _, err := a.RemoveKey(oldKey, "", 0); err != nil {
   244  		t.Fatalf("err: %v", err)
   245  	}
   246  
   247  	// Make sure only the new key remains
   248  	list, err := a.ListKeys("", 0)
   249  	if err != nil {
   250  		t.Fatalf("err: %v", err)
   251  	}
   252  	responses := list.Responses
   253  	if len(responses) != 2 {
   254  		t.Fatalf("bad: %d", len(responses))
   255  	}
   256  	for _, response := range responses {
   257  		if len(response.Keys) != 1 {
   258  			t.Fatalf("bad: %d", len(response.Keys))
   259  		}
   260  		if _, ok := response.Keys[newKey]; !ok {
   261  			t.Fatalf("bad: %v", ok)
   262  		}
   263  	}
   264  }
   265  
   266  func TestOperator_Keyring_InvalidRelayFactor(t *testing.T) {
   267  	t.Parallel()
   268  	key := "H3/9gBxcKKRf45CaI2DlRg=="
   269  	a := NewTestAgent(t, t.Name(), `
   270  		encrypt = "`+key+`"
   271  	`)
   272  	defer a.Shutdown()
   273  
   274  	cases := map[string]string{
   275  		"999":  "Relay factor must be in range",
   276  		"asdf": "Error parsing relay factor",
   277  	}
   278  	for relayFactor, errString := range cases {
   279  		req, _ := http.NewRequest("GET", "/v1/operator/keyring?relay-factor="+relayFactor, nil)
   280  		resp := httptest.NewRecorder()
   281  		_, err := a.srv.OperatorKeyringEndpoint(resp, req)
   282  		if err != nil {
   283  			t.Fatalf("err: %v", err)
   284  		}
   285  		body := resp.Body.String()
   286  		if !strings.Contains(body, errString) {
   287  			t.Fatalf("bad: %v", body)
   288  		}
   289  	}
   290  }
   291  
   292  func TestOperator_AutopilotGetConfiguration(t *testing.T) {
   293  	t.Parallel()
   294  	a := NewTestAgent(t, t.Name(), "")
   295  	defer a.Shutdown()
   296  	testrpc.WaitForTestAgent(t, a.RPC, "dc1")
   297  
   298  	body := bytes.NewBuffer(nil)
   299  	req, _ := http.NewRequest("GET", "/v1/operator/autopilot/configuration", body)
   300  	resp := httptest.NewRecorder()
   301  	obj, err := a.srv.OperatorAutopilotConfiguration(resp, req)
   302  	if err != nil {
   303  		t.Fatalf("err: %v", err)
   304  	}
   305  	if resp.Code != 200 {
   306  		t.Fatalf("bad code: %d", resp.Code)
   307  	}
   308  	out, ok := obj.(api.AutopilotConfiguration)
   309  	if !ok {
   310  		t.Fatalf("unexpected: %T", obj)
   311  	}
   312  	if !out.CleanupDeadServers {
   313  		t.Fatalf("bad: %#v", out)
   314  	}
   315  }
   316  
   317  func TestOperator_AutopilotSetConfiguration(t *testing.T) {
   318  	t.Parallel()
   319  	a := NewTestAgent(t, t.Name(), "")
   320  	defer a.Shutdown()
   321  
   322  	body := bytes.NewBuffer([]byte(`{"CleanupDeadServers": false}`))
   323  	req, _ := http.NewRequest("PUT", "/v1/operator/autopilot/configuration", body)
   324  	resp := httptest.NewRecorder()
   325  	if _, err := a.srv.OperatorAutopilotConfiguration(resp, req); err != nil {
   326  		t.Fatalf("err: %v", err)
   327  	}
   328  	if resp.Code != 200 {
   329  		t.Fatalf("bad code: %d", resp.Code)
   330  	}
   331  
   332  	args := structs.DCSpecificRequest{
   333  		Datacenter: "dc1",
   334  	}
   335  
   336  	var reply autopilot.Config
   337  	if err := a.RPC("Operator.AutopilotGetConfiguration", &args, &reply); err != nil {
   338  		t.Fatalf("err: %v", err)
   339  	}
   340  	if reply.CleanupDeadServers {
   341  		t.Fatalf("bad: %#v", reply)
   342  	}
   343  }
   344  
   345  func TestOperator_AutopilotCASConfiguration(t *testing.T) {
   346  	t.Parallel()
   347  	a := NewTestAgent(t, t.Name(), "")
   348  	defer a.Shutdown()
   349  
   350  	body := bytes.NewBuffer([]byte(`{"CleanupDeadServers": false}`))
   351  	req, _ := http.NewRequest("PUT", "/v1/operator/autopilot/configuration", body)
   352  	resp := httptest.NewRecorder()
   353  	if _, err := a.srv.OperatorAutopilotConfiguration(resp, req); err != nil {
   354  		t.Fatalf("err: %v", err)
   355  	}
   356  	if resp.Code != 200 {
   357  		t.Fatalf("bad code: %d", resp.Code)
   358  	}
   359  
   360  	args := structs.DCSpecificRequest{
   361  		Datacenter: "dc1",
   362  	}
   363  
   364  	var reply autopilot.Config
   365  	if err := a.RPC("Operator.AutopilotGetConfiguration", &args, &reply); err != nil {
   366  		t.Fatalf("err: %v", err)
   367  	}
   368  
   369  	if reply.CleanupDeadServers {
   370  		t.Fatalf("bad: %#v", reply)
   371  	}
   372  
   373  	// Create a CAS request, bad index
   374  	{
   375  		buf := bytes.NewBuffer([]byte(`{"CleanupDeadServers": true}`))
   376  		req, _ := http.NewRequest("PUT", fmt.Sprintf("/v1/operator/autopilot/configuration?cas=%d", reply.ModifyIndex-1), buf)
   377  		resp := httptest.NewRecorder()
   378  		obj, err := a.srv.OperatorAutopilotConfiguration(resp, req)
   379  		if err != nil {
   380  			t.Fatalf("err: %v", err)
   381  		}
   382  
   383  		if res := obj.(bool); res {
   384  			t.Fatalf("should NOT work")
   385  		}
   386  	}
   387  
   388  	// Create a CAS request, good index
   389  	{
   390  		buf := bytes.NewBuffer([]byte(`{"CleanupDeadServers": true}`))
   391  		req, _ := http.NewRequest("PUT", fmt.Sprintf("/v1/operator/autopilot/configuration?cas=%d", reply.ModifyIndex), buf)
   392  		resp := httptest.NewRecorder()
   393  		obj, err := a.srv.OperatorAutopilotConfiguration(resp, req)
   394  		if err != nil {
   395  			t.Fatalf("err: %v", err)
   396  		}
   397  
   398  		if res := obj.(bool); !res {
   399  			t.Fatalf("should work")
   400  		}
   401  	}
   402  
   403  	// Verify the update
   404  	if err := a.RPC("Operator.AutopilotGetConfiguration", &args, &reply); err != nil {
   405  		t.Fatalf("err: %v", err)
   406  	}
   407  	if !reply.CleanupDeadServers {
   408  		t.Fatalf("bad: %#v", reply)
   409  	}
   410  }
   411  
   412  func TestOperator_ServerHealth(t *testing.T) {
   413  	t.Parallel()
   414  	a := NewTestAgent(t, t.Name(), `
   415  		raft_protocol = 3
   416  	`)
   417  	defer a.Shutdown()
   418  
   419  	body := bytes.NewBuffer(nil)
   420  	req, _ := http.NewRequest("GET", "/v1/operator/autopilot/health", body)
   421  	retry.Run(t, func(r *retry.R) {
   422  		resp := httptest.NewRecorder()
   423  		obj, err := a.srv.OperatorServerHealth(resp, req)
   424  		if err != nil {
   425  			r.Fatalf("err: %v", err)
   426  		}
   427  		if resp.Code != 200 {
   428  			r.Fatalf("bad code: %d", resp.Code)
   429  		}
   430  		out, ok := obj.(*api.OperatorHealthReply)
   431  		if !ok {
   432  			r.Fatalf("unexpected: %T", obj)
   433  		}
   434  		if len(out.Servers) != 1 ||
   435  			!out.Servers[0].Healthy ||
   436  			out.Servers[0].Name != a.Config.NodeName ||
   437  			out.Servers[0].SerfStatus != "alive" ||
   438  			out.FailureTolerance != 0 {
   439  			r.Fatalf("bad: %v", out)
   440  		}
   441  	})
   442  }
   443  
   444  func TestOperator_ServerHealth_Unhealthy(t *testing.T) {
   445  	t.Parallel()
   446  	a := NewTestAgent(t, t.Name(), `
   447  		raft_protocol = 3
   448  		autopilot {
   449  			last_contact_threshold = "-1s"
   450  		}
   451  	`)
   452  	defer a.Shutdown()
   453  
   454  	body := bytes.NewBuffer(nil)
   455  	req, _ := http.NewRequest("GET", "/v1/operator/autopilot/health", body)
   456  	retry.Run(t, func(r *retry.R) {
   457  		resp := httptest.NewRecorder()
   458  		obj, err := a.srv.OperatorServerHealth(resp, req)
   459  		if err != nil {
   460  			r.Fatalf("err: %v", err)
   461  		}
   462  		if resp.Code != 429 {
   463  			r.Fatalf("bad code: %d", resp.Code)
   464  		}
   465  		out, ok := obj.(*api.OperatorHealthReply)
   466  		if !ok {
   467  			r.Fatalf("unexpected: %T", obj)
   468  		}
   469  		if len(out.Servers) != 1 ||
   470  			out.Healthy ||
   471  			out.Servers[0].Name != a.Config.NodeName {
   472  			r.Fatalf("bad: %#v", out.Servers)
   473  		}
   474  	})
   475  }