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

     1  package agent
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  	"fmt"
     7  	"net/http"
     8  	"net/http/httptest"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/hashicorp/consul/testrpc"
    13  
    14  	"github.com/hashicorp/consul/acl"
    15  	"github.com/hashicorp/consul/agent/structs"
    16  	"github.com/hashicorp/consul/testutil/retry"
    17  )
    18  
    19  func TestEventFire(t *testing.T) {
    20  	t.Parallel()
    21  	a := NewTestAgent(t, t.Name(), "")
    22  	defer a.Shutdown()
    23  	testrpc.WaitForTestAgent(t, a.RPC, "dc1")
    24  
    25  	body := bytes.NewBuffer([]byte("test"))
    26  	url := "/v1/event/fire/test?node=Node&service=foo&tag=bar"
    27  	req, _ := http.NewRequest("PUT", url, body)
    28  	resp := httptest.NewRecorder()
    29  	obj, err := a.srv.EventFire(resp, req)
    30  	if err != nil {
    31  		t.Fatalf("err: %v", err)
    32  	}
    33  
    34  	event, ok := obj.(*UserEvent)
    35  	if !ok {
    36  		t.Fatalf("bad: %#v", obj)
    37  	}
    38  
    39  	if event.ID == "" {
    40  		t.Fatalf("bad: %#v", event)
    41  	}
    42  	if event.Name != "test" {
    43  		t.Fatalf("bad: %#v", event)
    44  	}
    45  	if string(event.Payload) != "test" {
    46  		t.Fatalf("bad: %#v", event)
    47  	}
    48  	if event.NodeFilter != "Node" {
    49  		t.Fatalf("bad: %#v", event)
    50  	}
    51  	if event.ServiceFilter != "foo" {
    52  		t.Fatalf("bad: %#v", event)
    53  	}
    54  	if event.TagFilter != "bar" {
    55  		t.Fatalf("bad: %#v", event)
    56  	}
    57  }
    58  
    59  func TestEventFire_token(t *testing.T) {
    60  	t.Parallel()
    61  	a := NewTestAgent(t, t.Name(), TestACLConfig()+`
    62  		acl_default_policy = "deny"
    63  	`)
    64  	defer a.Shutdown()
    65  	testrpc.WaitForLeader(t, a.RPC, "dc1")
    66  
    67  	// Create an ACL token
    68  	args := structs.ACLRequest{
    69  		Datacenter: "dc1",
    70  		Op:         structs.ACLSet,
    71  		ACL: structs.ACL{
    72  			Name:  "User token",
    73  			Type:  structs.ACLTokenTypeClient,
    74  			Rules: testEventPolicy,
    75  		},
    76  		WriteRequest: structs.WriteRequest{Token: "root"},
    77  	}
    78  	var token string
    79  	if err := a.RPC("ACL.Apply", &args, &token); err != nil {
    80  		t.Fatalf("err: %v", err)
    81  	}
    82  
    83  	type tcase struct {
    84  		event   string
    85  		allowed bool
    86  	}
    87  	tcases := []tcase{
    88  		{"foo", false},
    89  		{"bar", false},
    90  		{"baz", true},
    91  	}
    92  	for _, c := range tcases {
    93  		// Try to fire the event over the HTTP interface
    94  		url := fmt.Sprintf("/v1/event/fire/%s?token=%s", c.event, token)
    95  		req, _ := http.NewRequest("PUT", url, nil)
    96  		resp := httptest.NewRecorder()
    97  		if _, err := a.srv.EventFire(resp, req); err != nil {
    98  			t.Fatalf("err: %s", err)
    99  		}
   100  
   101  		// Check the result
   102  		body := resp.Body.String()
   103  		if c.allowed {
   104  			if acl.IsErrPermissionDenied(errors.New(body)) {
   105  				t.Fatalf("bad: %s", body)
   106  			}
   107  			if resp.Code != 200 {
   108  				t.Fatalf("bad: %d", resp.Code)
   109  			}
   110  		} else {
   111  			if !acl.IsErrPermissionDenied(errors.New(body)) {
   112  				t.Fatalf("bad: %s", body)
   113  			}
   114  			if resp.Code != 403 {
   115  				t.Fatalf("bad: %d", resp.Code)
   116  			}
   117  		}
   118  	}
   119  }
   120  
   121  func TestEventList(t *testing.T) {
   122  	t.Parallel()
   123  	a := NewTestAgent(t, t.Name(), "")
   124  	defer a.Shutdown()
   125  	testrpc.WaitForTestAgent(t, a.RPC, "dc1")
   126  
   127  	p := &UserEvent{Name: "test"}
   128  	if err := a.UserEvent("dc1", "root", p); err != nil {
   129  		t.Fatalf("err: %v", err)
   130  	}
   131  
   132  	retry.Run(t, func(r *retry.R) {
   133  		req, _ := http.NewRequest("GET", "/v1/event/list", nil)
   134  		resp := httptest.NewRecorder()
   135  		obj, err := a.srv.EventList(resp, req)
   136  		if err != nil {
   137  			r.Fatal(err)
   138  		}
   139  
   140  		list, ok := obj.([]*UserEvent)
   141  		if !ok {
   142  			r.Fatalf("bad: %#v", obj)
   143  		}
   144  		if len(list) != 1 || list[0].Name != "test" {
   145  			r.Fatalf("bad: %#v", list)
   146  		}
   147  		header := resp.Header().Get("X-Consul-Index")
   148  		if header == "" || header == "0" {
   149  			r.Fatalf("bad: %#v", header)
   150  		}
   151  	})
   152  }
   153  
   154  func TestEventList_Filter(t *testing.T) {
   155  	t.Parallel()
   156  	a := NewTestAgent(t, t.Name(), "")
   157  	defer a.Shutdown()
   158  	testrpc.WaitForTestAgent(t, a.RPC, "dc1")
   159  
   160  	p := &UserEvent{Name: "test"}
   161  	if err := a.UserEvent("dc1", "root", p); err != nil {
   162  		t.Fatalf("err: %v", err)
   163  	}
   164  
   165  	p = &UserEvent{Name: "foo"}
   166  	if err := a.UserEvent("dc1", "root", p); err != nil {
   167  		t.Fatalf("err: %v", err)
   168  	}
   169  
   170  	retry.Run(t, func(r *retry.R) {
   171  		req, _ := http.NewRequest("GET", "/v1/event/list?name=foo", nil)
   172  		resp := httptest.NewRecorder()
   173  		obj, err := a.srv.EventList(resp, req)
   174  		if err != nil {
   175  			r.Fatal(err)
   176  		}
   177  
   178  		list, ok := obj.([]*UserEvent)
   179  		if !ok {
   180  			r.Fatalf("bad: %#v", obj)
   181  		}
   182  		if len(list) != 1 || list[0].Name != "foo" {
   183  			r.Fatalf("bad: %#v", list)
   184  		}
   185  		header := resp.Header().Get("X-Consul-Index")
   186  		if header == "" || header == "0" {
   187  			r.Fatalf("bad: %#v", header)
   188  		}
   189  	})
   190  }
   191  
   192  func TestEventList_ACLFilter(t *testing.T) {
   193  	t.Parallel()
   194  	a := NewTestAgent(t, t.Name(), TestACLConfig())
   195  	defer a.Shutdown()
   196  	testrpc.WaitForLeader(t, a.RPC, "dc1")
   197  
   198  	// Fire an event.
   199  	p := &UserEvent{Name: "foo"}
   200  	if err := a.UserEvent("dc1", "root", p); err != nil {
   201  		t.Fatalf("err: %v", err)
   202  	}
   203  
   204  	t.Run("no token", func(t *testing.T) {
   205  		retry.Run(t, func(r *retry.R) {
   206  			req, _ := http.NewRequest("GET", "/v1/event/list", nil)
   207  			resp := httptest.NewRecorder()
   208  			obj, err := a.srv.EventList(resp, req)
   209  			if err != nil {
   210  				r.Fatal(err)
   211  			}
   212  
   213  			list, ok := obj.([]*UserEvent)
   214  			if !ok {
   215  				r.Fatalf("bad: %#v", obj)
   216  			}
   217  			if len(list) != 0 {
   218  				r.Fatalf("bad: %#v", list)
   219  			}
   220  		})
   221  	})
   222  
   223  	t.Run("root token", func(t *testing.T) {
   224  		retry.Run(t, func(r *retry.R) {
   225  			req, _ := http.NewRequest("GET", "/v1/event/list?token=root", nil)
   226  			resp := httptest.NewRecorder()
   227  			obj, err := a.srv.EventList(resp, req)
   228  			if err != nil {
   229  				r.Fatal(err)
   230  			}
   231  
   232  			list, ok := obj.([]*UserEvent)
   233  			if !ok {
   234  				r.Fatalf("bad: %#v", obj)
   235  			}
   236  			if len(list) != 1 || list[0].Name != "foo" {
   237  				r.Fatalf("bad: %#v", list)
   238  			}
   239  		})
   240  	})
   241  }
   242  
   243  func TestEventList_Blocking(t *testing.T) {
   244  	t.Parallel()
   245  	a := NewTestAgent(t, t.Name(), "")
   246  	defer a.Shutdown()
   247  	testrpc.WaitForTestAgent(t, a.RPC, "dc1")
   248  
   249  	p := &UserEvent{Name: "test"}
   250  	if err := a.UserEvent("dc1", "root", p); err != nil {
   251  		t.Fatalf("err: %v", err)
   252  	}
   253  
   254  	var index string
   255  	retry.Run(t, func(r *retry.R) {
   256  		req, _ := http.NewRequest("GET", "/v1/event/list", nil)
   257  		resp := httptest.NewRecorder()
   258  		if _, err := a.srv.EventList(resp, req); err != nil {
   259  			r.Fatal(err)
   260  		}
   261  		header := resp.Header().Get("X-Consul-Index")
   262  		if header == "" || header == "0" {
   263  			r.Fatalf("bad: %#v", header)
   264  		}
   265  		index = header
   266  	})
   267  
   268  	go func() {
   269  		time.Sleep(50 * time.Millisecond)
   270  		p := &UserEvent{Name: "second"}
   271  		if err := a.UserEvent("dc1", "root", p); err != nil {
   272  			t.Fatalf("err: %v", err)
   273  		}
   274  	}()
   275  
   276  	retry.Run(t, func(r *retry.R) {
   277  		url := "/v1/event/list?index=" + index
   278  		req, _ := http.NewRequest("GET", url, nil)
   279  		resp := httptest.NewRecorder()
   280  		obj, err := a.srv.EventList(resp, req)
   281  		if err != nil {
   282  			r.Fatal(err)
   283  		}
   284  
   285  		list, ok := obj.([]*UserEvent)
   286  		if !ok {
   287  			r.Fatalf("bad: %#v", obj)
   288  		}
   289  		if len(list) != 2 || list[1].Name != "second" {
   290  			r.Fatalf("bad: %#v", list)
   291  		}
   292  	})
   293  }
   294  
   295  func TestEventList_EventBufOrder(t *testing.T) {
   296  	t.Parallel()
   297  	a := NewTestAgent(t, t.Name(), "")
   298  	defer a.Shutdown()
   299  	testrpc.WaitForTestAgent(t, a.RPC, "dc1")
   300  
   301  	// Fire some events in a non-sequential order
   302  	expected := &UserEvent{Name: "foo"}
   303  
   304  	for _, e := range []*UserEvent{
   305  		&UserEvent{Name: "foo"},
   306  		&UserEvent{Name: "bar"},
   307  		&UserEvent{Name: "foo"},
   308  		expected,
   309  		&UserEvent{Name: "bar"},
   310  	} {
   311  		if err := a.UserEvent("dc1", "root", e); err != nil {
   312  			t.Fatalf("err: %v", err)
   313  		}
   314  	}
   315  	// Test that the event order is preserved when name
   316  	// filtering on a list of > 1 matching event.
   317  	retry.Run(t, func(r *retry.R) {
   318  		url := "/v1/event/list?name=foo"
   319  		req, _ := http.NewRequest("GET", url, nil)
   320  		resp := httptest.NewRecorder()
   321  		obj, err := a.srv.EventList(resp, req)
   322  		if err != nil {
   323  			r.Fatal(err)
   324  		}
   325  		list, ok := obj.([]*UserEvent)
   326  		if !ok {
   327  			r.Fatalf("bad: %#v", obj)
   328  		}
   329  		if len(list) != 3 || list[2].ID != expected.ID {
   330  			r.Fatalf("bad: %#v", list)
   331  		}
   332  	})
   333  }
   334  
   335  func TestUUIDToUint64(t *testing.T) {
   336  	t.Parallel()
   337  	inp := "cb9a81ad-fff6-52ac-92a7-5f70687805ec"
   338  
   339  	// Output value was computed using python
   340  	if uuidToUint64(inp) != 6430540886266763072 {
   341  		t.Fatalf("bad")
   342  	}
   343  }