github.com/clly/consul@v1.4.5/agent/consul/catalog_endpoint_test.go (about)

     1  package consul
     2  
     3  import (
     4  	"fmt"
     5  	"net/rpc"
     6  	"os"
     7  	"strings"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/hashicorp/consul/acl"
    12  	"github.com/hashicorp/consul/agent/structs"
    13  	"github.com/hashicorp/consul/api"
    14  	"github.com/hashicorp/consul/lib"
    15  	"github.com/hashicorp/consul/testrpc"
    16  	"github.com/hashicorp/consul/testutil/retry"
    17  	"github.com/hashicorp/consul/types"
    18  	"github.com/hashicorp/net-rpc-msgpackrpc"
    19  	"github.com/stretchr/testify/assert"
    20  	"github.com/stretchr/testify/require"
    21  )
    22  
    23  func TestCatalog_Register(t *testing.T) {
    24  	t.Parallel()
    25  	dir1, s1 := testServer(t)
    26  	defer os.RemoveAll(dir1)
    27  	defer s1.Shutdown()
    28  	codec := rpcClient(t, s1)
    29  	defer codec.Close()
    30  
    31  	arg := structs.RegisterRequest{
    32  		Datacenter: "dc1",
    33  		Node:       "foo",
    34  		Address:    "127.0.0.1",
    35  		Service: &structs.NodeService{
    36  			Service: "db",
    37  			Tags:    []string{"master"},
    38  			Port:    8000,
    39  		},
    40  		Check: &structs.HealthCheck{
    41  			CheckID:   types.CheckID("db-check"),
    42  			ServiceID: "db",
    43  		},
    44  	}
    45  	var out struct{}
    46  
    47  	err := msgpackrpc.CallWithCodec(codec, "Catalog.Register", &arg, &out)
    48  	if err != nil {
    49  		t.Fatalf("err: %v", err)
    50  	}
    51  }
    52  
    53  func TestCatalog_RegisterService_InvalidAddress(t *testing.T) {
    54  	t.Parallel()
    55  	dir1, s1 := testServer(t)
    56  	defer os.RemoveAll(dir1)
    57  	defer s1.Shutdown()
    58  	codec := rpcClient(t, s1)
    59  	defer codec.Close()
    60  
    61  	for _, addr := range []string{"0.0.0.0", "::", "[::]"} {
    62  		t.Run("addr "+addr, func(t *testing.T) {
    63  			arg := structs.RegisterRequest{
    64  				Datacenter: "dc1",
    65  				Node:       "foo",
    66  				Address:    "127.0.0.1",
    67  				Service: &structs.NodeService{
    68  					Service: "db",
    69  					Address: addr,
    70  					Port:    8000,
    71  				},
    72  			}
    73  			var out struct{}
    74  
    75  			err := msgpackrpc.CallWithCodec(codec, "Catalog.Register", &arg, &out)
    76  			if err == nil || err.Error() != "Invalid service address" {
    77  				t.Fatalf("got error %v want 'Invalid service address'", err)
    78  			}
    79  		})
    80  	}
    81  }
    82  
    83  func TestCatalog_RegisterService_SkipNodeUpdate(t *testing.T) {
    84  	t.Parallel()
    85  	dir1, s1 := testServer(t)
    86  	defer os.RemoveAll(dir1)
    87  	defer s1.Shutdown()
    88  	codec := rpcClient(t, s1)
    89  	defer codec.Close()
    90  
    91  	// Register a node
    92  	arg := structs.RegisterRequest{
    93  		Datacenter: "dc1",
    94  		Node:       "foo",
    95  		Address:    "127.0.0.1",
    96  	}
    97  	var out struct{}
    98  	err := msgpackrpc.CallWithCodec(codec, "Catalog.Register", &arg, &out)
    99  	if err != nil {
   100  		t.Fatal(err)
   101  	}
   102  
   103  	// Update it with a blank address, should fail.
   104  	arg.Address = ""
   105  	arg.Service = &structs.NodeService{
   106  		Service: "db",
   107  		Port:    8000,
   108  	}
   109  	err = msgpackrpc.CallWithCodec(codec, "Catalog.Register", &arg, &out)
   110  	if err == nil || err.Error() != "Must provide address if SkipNodeUpdate is not set" {
   111  		t.Fatalf("got error %v want 'Must provide address...'", err)
   112  	}
   113  
   114  	// Set SkipNodeUpdate, should succeed
   115  	arg.SkipNodeUpdate = true
   116  	err = msgpackrpc.CallWithCodec(codec, "Catalog.Register", &arg, &out)
   117  	if err != nil {
   118  		t.Fatal(err)
   119  	}
   120  }
   121  
   122  func TestCatalog_Register_NodeID(t *testing.T) {
   123  	t.Parallel()
   124  	dir1, s1 := testServer(t)
   125  	defer os.RemoveAll(dir1)
   126  	defer s1.Shutdown()
   127  	codec := rpcClient(t, s1)
   128  	defer codec.Close()
   129  
   130  	arg := structs.RegisterRequest{
   131  		Datacenter: "dc1",
   132  		ID:         "nope",
   133  		Node:       "foo",
   134  		Address:    "127.0.0.1",
   135  		Service: &structs.NodeService{
   136  			Service: "db",
   137  			Tags:    []string{"master"},
   138  			Port:    8000,
   139  		},
   140  		Check: &structs.HealthCheck{
   141  			CheckID:   types.CheckID("db-check"),
   142  			ServiceID: "db",
   143  		},
   144  	}
   145  	var out struct{}
   146  
   147  	err := msgpackrpc.CallWithCodec(codec, "Catalog.Register", &arg, &out)
   148  	if err == nil || !strings.Contains(err.Error(), "Bad node ID") {
   149  		t.Fatalf("err: %v", err)
   150  	}
   151  
   152  	arg.ID = types.NodeID("adf4238a-882b-9ddc-4a9d-5b6758e4159e")
   153  	if err := msgpackrpc.CallWithCodec(codec, "Catalog.Register", &arg, &out); err != nil {
   154  		t.Fatalf("err: %v", err)
   155  	}
   156  }
   157  
   158  func TestCatalog_Register_ACLDeny(t *testing.T) {
   159  	t.Parallel()
   160  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
   161  		c.ACLDatacenter = "dc1"
   162  		c.ACLsEnabled = true
   163  		c.ACLMasterToken = "root"
   164  		c.ACLDefaultPolicy = "deny"
   165  		c.ACLEnforceVersion8 = false
   166  	})
   167  	defer os.RemoveAll(dir1)
   168  	defer s1.Shutdown()
   169  	testrpc.WaitForTestAgent(t, s1.RPC, "dc1")
   170  	codec := rpcClient(t, s1)
   171  	defer codec.Close()
   172  
   173  	// Create the ACL.
   174  	arg := structs.ACLRequest{
   175  		Datacenter: "dc1",
   176  		Op:         structs.ACLSet,
   177  		ACL: structs.ACL{
   178  			Name: "User token",
   179  			Type: structs.ACLTokenTypeClient,
   180  			Rules: `
   181  service "foo" {
   182  	policy = "write"
   183  }
   184  `,
   185  		},
   186  		WriteRequest: structs.WriteRequest{Token: "root"},
   187  	}
   188  	var id string
   189  	if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &arg, &id); err != nil {
   190  		t.Fatalf("err: %v", err)
   191  	}
   192  
   193  	argR := structs.RegisterRequest{
   194  		Datacenter: "dc1",
   195  		Node:       "foo",
   196  		Address:    "127.0.0.1",
   197  		Service: &structs.NodeService{
   198  			Service: "db",
   199  			Tags:    []string{"master"},
   200  			Port:    8000,
   201  		},
   202  		WriteRequest: structs.WriteRequest{Token: id},
   203  	}
   204  	var outR struct{}
   205  
   206  	// This should fail since we are writing to the "db" service, which isn't
   207  	// allowed.
   208  	err := msgpackrpc.CallWithCodec(codec, "Catalog.Register", &argR, &outR)
   209  	if !acl.IsErrPermissionDenied(err) {
   210  		t.Fatalf("err: %v", err)
   211  	}
   212  
   213  	// The "foo" service should work, though.
   214  	argR.Service.Service = "foo"
   215  	err = msgpackrpc.CallWithCodec(codec, "Catalog.Register", &argR, &outR)
   216  	if err != nil {
   217  		t.Fatalf("err: %v", err)
   218  	}
   219  
   220  	// Try the special case for the "consul" service that allows it no matter
   221  	// what with pre-version 8 ACL enforcement.
   222  	argR.Service.Service = "consul"
   223  	err = msgpackrpc.CallWithCodec(codec, "Catalog.Register", &argR, &outR)
   224  	if err != nil {
   225  		t.Fatalf("err: %v", err)
   226  	}
   227  
   228  	// Make sure the exception goes away when we turn on version 8 ACL
   229  	// enforcement.
   230  	s1.config.ACLEnforceVersion8 = true
   231  	err = msgpackrpc.CallWithCodec(codec, "Catalog.Register", &argR, &outR)
   232  	if !acl.IsErrPermissionDenied(err) {
   233  		t.Fatalf("err: %v", err)
   234  	}
   235  
   236  	// Register a db service using the root token.
   237  	argR.Service.Service = "db"
   238  	argR.Service.ID = "my-id"
   239  	argR.Token = "root"
   240  	err = msgpackrpc.CallWithCodec(codec, "Catalog.Register", &argR, &outR)
   241  	if err != nil {
   242  		t.Fatalf("err: %v", err)
   243  	}
   244  
   245  	// Prove that we are properly looking up the node services and passing
   246  	// that to the ACL helper. We can vet the helper independently in its
   247  	// own unit test after this. This is trying to register over the db
   248  	// service we created above, which is a check that depends on looking
   249  	// at the existing registration data with that service ID. This is a new
   250  	// check for version 8.
   251  	argR.Service.Service = "foo"
   252  	argR.Service.ID = "my-id"
   253  	argR.Token = id
   254  	err = msgpackrpc.CallWithCodec(codec, "Catalog.Register", &argR, &outR)
   255  	if !acl.IsErrPermissionDenied(err) {
   256  		t.Fatalf("err: %v", err)
   257  	}
   258  }
   259  
   260  func TestCatalog_Register_ForwardLeader(t *testing.T) {
   261  	t.Parallel()
   262  	dir1, s1 := testServer(t)
   263  	defer os.RemoveAll(dir1)
   264  	defer s1.Shutdown()
   265  	codec1 := rpcClient(t, s1)
   266  	defer codec1.Close()
   267  
   268  	dir2, s2 := testServer(t)
   269  	defer os.RemoveAll(dir2)
   270  	defer s2.Shutdown()
   271  	codec2 := rpcClient(t, s2)
   272  	defer codec2.Close()
   273  
   274  	// Try to join
   275  	joinLAN(t, s2, s1)
   276  
   277  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
   278  	testrpc.WaitForLeader(t, s2.RPC, "dc1")
   279  
   280  	// Use the follower as the client
   281  	var codec rpc.ClientCodec
   282  	if !s1.IsLeader() {
   283  		codec = codec1
   284  	} else {
   285  		codec = codec2
   286  	}
   287  
   288  	arg := structs.RegisterRequest{
   289  		Datacenter: "dc1",
   290  		Node:       "foo",
   291  		Address:    "127.0.0.1",
   292  		Service: &structs.NodeService{
   293  			Service: "db",
   294  			Tags:    []string{"master"},
   295  			Port:    8000,
   296  		},
   297  	}
   298  	var out struct{}
   299  	if err := msgpackrpc.CallWithCodec(codec, "Catalog.Register", &arg, &out); err != nil {
   300  		t.Fatalf("err: %v", err)
   301  	}
   302  }
   303  
   304  func TestCatalog_Register_ForwardDC(t *testing.T) {
   305  	t.Parallel()
   306  	dir1, s1 := testServer(t)
   307  	defer os.RemoveAll(dir1)
   308  	defer s1.Shutdown()
   309  	codec := rpcClient(t, s1)
   310  	defer codec.Close()
   311  
   312  	dir2, s2 := testServerDC(t, "dc2")
   313  	defer os.RemoveAll(dir2)
   314  	defer s2.Shutdown()
   315  
   316  	// Try to join
   317  	joinWAN(t, s2, s1)
   318  
   319  	testrpc.WaitForLeader(t, s1.RPC, "dc2")
   320  
   321  	arg := structs.RegisterRequest{
   322  		Datacenter: "dc2", // Should forward through s1
   323  		Node:       "foo",
   324  		Address:    "127.0.0.1",
   325  		Service: &structs.NodeService{
   326  			Service: "db",
   327  			Tags:    []string{"master"},
   328  			Port:    8000,
   329  		},
   330  	}
   331  	var out struct{}
   332  	if err := msgpackrpc.CallWithCodec(codec, "Catalog.Register", &arg, &out); err != nil {
   333  		t.Fatalf("err: %v", err)
   334  	}
   335  }
   336  
   337  func TestCatalog_Register_ConnectProxy(t *testing.T) {
   338  	t.Parallel()
   339  
   340  	assert := assert.New(t)
   341  	dir1, s1 := testServer(t)
   342  	defer os.RemoveAll(dir1)
   343  	defer s1.Shutdown()
   344  	codec := rpcClient(t, s1)
   345  	defer codec.Close()
   346  
   347  	args := structs.TestRegisterRequestProxy(t)
   348  
   349  	// Register
   350  	var out struct{}
   351  	assert.Nil(msgpackrpc.CallWithCodec(codec, "Catalog.Register", &args, &out))
   352  
   353  	// List
   354  	req := structs.ServiceSpecificRequest{
   355  		Datacenter:  "dc1",
   356  		ServiceName: args.Service.Service,
   357  	}
   358  	var resp structs.IndexedServiceNodes
   359  	assert.Nil(msgpackrpc.CallWithCodec(codec, "Catalog.ServiceNodes", &req, &resp))
   360  	assert.Len(resp.ServiceNodes, 1)
   361  	v := resp.ServiceNodes[0]
   362  	assert.Equal(structs.ServiceKindConnectProxy, v.ServiceKind)
   363  	assert.Equal(args.Service.Proxy.DestinationServiceName, v.ServiceProxy.DestinationServiceName)
   364  }
   365  
   366  // DEPRECATED (ProxyDestination) - remove this whole test case when removing
   367  // ProxyDestination
   368  func TestCatalog_Register_DeprecatedConnectProxy(t *testing.T) {
   369  	t.Parallel()
   370  
   371  	assert := assert.New(t)
   372  	dir1, s1 := testServer(t)
   373  	defer os.RemoveAll(dir1)
   374  	defer s1.Shutdown()
   375  	codec := rpcClient(t, s1)
   376  	defer codec.Close()
   377  
   378  	args := structs.TestRegisterRequestProxy(t)
   379  	args.Service.ProxyDestination = "legacy"
   380  	args.Service.Proxy = structs.ConnectProxyConfig{}
   381  
   382  	// Register
   383  	var out struct{}
   384  	assert.Nil(msgpackrpc.CallWithCodec(codec, "Catalog.Register", &args, &out))
   385  
   386  	// List
   387  	req := structs.ServiceSpecificRequest{
   388  		Datacenter:  "dc1",
   389  		ServiceName: args.Service.Service,
   390  	}
   391  	var resp structs.IndexedServiceNodes
   392  	assert.Nil(msgpackrpc.CallWithCodec(codec, "Catalog.ServiceNodes", &req, &resp))
   393  	assert.Len(resp.ServiceNodes, 1)
   394  	v := resp.ServiceNodes[0]
   395  	assert.Equal(structs.ServiceKindConnectProxy, v.ServiceKind)
   396  	assert.Equal(args.Service.ProxyDestination, v.ServiceProxy.DestinationServiceName)
   397  }
   398  
   399  // Test an invalid ConnectProxy. We don't need to exhaustively test because
   400  // this is all tested in structs on the Validate method.
   401  func TestCatalog_Register_ConnectProxy_invalid(t *testing.T) {
   402  	t.Parallel()
   403  
   404  	assert := assert.New(t)
   405  	dir1, s1 := testServer(t)
   406  	defer os.RemoveAll(dir1)
   407  	defer s1.Shutdown()
   408  	codec := rpcClient(t, s1)
   409  	defer codec.Close()
   410  
   411  	args := structs.TestRegisterRequestProxy(t)
   412  	args.Service.Proxy.DestinationServiceName = ""
   413  
   414  	// Register
   415  	var out struct{}
   416  	err := msgpackrpc.CallWithCodec(codec, "Catalog.Register", &args, &out)
   417  	assert.NotNil(err)
   418  	assert.Contains(err.Error(), "DestinationServiceName")
   419  }
   420  
   421  // Test that write is required for the proxy destination to register a proxy.
   422  func TestCatalog_Register_ConnectProxy_ACLProxyDestination(t *testing.T) {
   423  	t.Parallel()
   424  
   425  	assert := assert.New(t)
   426  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
   427  		c.ACLDatacenter = "dc1"
   428  		c.ACLsEnabled = true
   429  		c.ACLMasterToken = "root"
   430  		c.ACLDefaultPolicy = "deny"
   431  	})
   432  	defer os.RemoveAll(dir1)
   433  	defer s1.Shutdown()
   434  	codec := rpcClient(t, s1)
   435  	defer codec.Close()
   436  
   437  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
   438  
   439  	// Create the ACL.
   440  	arg := structs.ACLRequest{
   441  		Datacenter: "dc1",
   442  		Op:         structs.ACLSet,
   443  		ACL: structs.ACL{
   444  			Name: "User token",
   445  			Type: structs.ACLTokenTypeClient,
   446  			Rules: `
   447  service "foo" {
   448  	policy = "write"
   449  }
   450  `,
   451  		},
   452  		WriteRequest: structs.WriteRequest{Token: "root"},
   453  	}
   454  	var token string
   455  	assert.Nil(msgpackrpc.CallWithCodec(codec, "ACL.Apply", &arg, &token))
   456  
   457  	// Register should fail because we don't have permission on the destination
   458  	args := structs.TestRegisterRequestProxy(t)
   459  	args.Service.Service = "foo"
   460  	args.Service.Proxy.DestinationServiceName = "bar"
   461  	args.WriteRequest.Token = token
   462  	var out struct{}
   463  	err := msgpackrpc.CallWithCodec(codec, "Catalog.Register", &args, &out)
   464  	assert.True(acl.IsErrPermissionDenied(err))
   465  
   466  	// Register should fail with the right destination but wrong name
   467  	args = structs.TestRegisterRequestProxy(t)
   468  	args.Service.Service = "bar"
   469  	args.Service.Proxy.DestinationServiceName = "foo"
   470  	args.WriteRequest.Token = token
   471  	err = msgpackrpc.CallWithCodec(codec, "Catalog.Register", &args, &out)
   472  	assert.True(acl.IsErrPermissionDenied(err))
   473  
   474  	// Register should work with the right destination
   475  	args = structs.TestRegisterRequestProxy(t)
   476  	args.Service.Service = "foo"
   477  	args.Service.Proxy.DestinationServiceName = "foo"
   478  	args.WriteRequest.Token = token
   479  	assert.Nil(msgpackrpc.CallWithCodec(codec, "Catalog.Register", &args, &out))
   480  }
   481  
   482  func TestCatalog_Register_ConnectNative(t *testing.T) {
   483  	t.Parallel()
   484  
   485  	assert := assert.New(t)
   486  	dir1, s1 := testServer(t)
   487  	defer os.RemoveAll(dir1)
   488  	defer s1.Shutdown()
   489  	codec := rpcClient(t, s1)
   490  	defer codec.Close()
   491  
   492  	args := structs.TestRegisterRequest(t)
   493  	args.Service.Connect.Native = true
   494  
   495  	// Register
   496  	var out struct{}
   497  	assert.Nil(msgpackrpc.CallWithCodec(codec, "Catalog.Register", &args, &out))
   498  
   499  	// List
   500  	req := structs.ServiceSpecificRequest{
   501  		Datacenter:  "dc1",
   502  		ServiceName: args.Service.Service,
   503  	}
   504  	var resp structs.IndexedServiceNodes
   505  	assert.Nil(msgpackrpc.CallWithCodec(codec, "Catalog.ServiceNodes", &req, &resp))
   506  	assert.Len(resp.ServiceNodes, 1)
   507  	v := resp.ServiceNodes[0]
   508  	assert.Equal(structs.ServiceKindTypical, v.ServiceKind)
   509  	assert.True(v.ServiceConnect.Native)
   510  }
   511  
   512  func TestCatalog_Deregister(t *testing.T) {
   513  	t.Parallel()
   514  	dir1, s1 := testServer(t)
   515  	defer os.RemoveAll(dir1)
   516  	defer s1.Shutdown()
   517  	codec := rpcClient(t, s1)
   518  	defer codec.Close()
   519  
   520  	arg := structs.DeregisterRequest{
   521  		Datacenter: "dc1",
   522  		Node:       "foo",
   523  	}
   524  	var out struct{}
   525  
   526  	err := msgpackrpc.CallWithCodec(codec, "Catalog.Deregister", &arg, &out)
   527  	if err != nil {
   528  		t.Fatalf("err: %v", err)
   529  	}
   530  
   531  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
   532  
   533  	if err := msgpackrpc.CallWithCodec(codec, "Catalog.Deregister", &arg, &out); err != nil {
   534  		t.Fatalf("err: %v", err)
   535  	}
   536  }
   537  
   538  func TestCatalog_Deregister_ACLDeny(t *testing.T) {
   539  	t.Parallel()
   540  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
   541  		c.ACLDatacenter = "dc1"
   542  		c.ACLsEnabled = true
   543  		c.ACLMasterToken = "root"
   544  		c.ACLDefaultPolicy = "deny"
   545  		c.ACLEnforceVersion8 = false
   546  	})
   547  	defer os.RemoveAll(dir1)
   548  	defer s1.Shutdown()
   549  	codec := rpcClient(t, s1)
   550  	defer codec.Close()
   551  
   552  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
   553  
   554  	// Create the ACL.
   555  	arg := structs.ACLRequest{
   556  		Datacenter: "dc1",
   557  		Op:         structs.ACLSet,
   558  		ACL: structs.ACL{
   559  			Name: "User token",
   560  			Type: structs.ACLTokenTypeClient,
   561  			Rules: `
   562  node "node" {
   563  	policy = "write"
   564  }
   565  
   566  service "service" {
   567  	policy = "write"
   568  }
   569  `,
   570  		},
   571  		WriteRequest: structs.WriteRequest{Token: "root"},
   572  	}
   573  	var id string
   574  	if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &arg, &id); err != nil {
   575  		t.Fatalf("err: %v", err)
   576  	}
   577  
   578  	// Register a node, node check, service, and service check.
   579  	argR := structs.RegisterRequest{
   580  		Datacenter: "dc1",
   581  		Node:       "node",
   582  		Address:    "127.0.0.1",
   583  		Service: &structs.NodeService{
   584  			Service: "service",
   585  			Port:    8000,
   586  		},
   587  		Checks: structs.HealthChecks{
   588  			&structs.HealthCheck{
   589  				Node:    "node",
   590  				CheckID: "node-check",
   591  			},
   592  			&structs.HealthCheck{
   593  				Node:      "node",
   594  				CheckID:   "service-check",
   595  				ServiceID: "service",
   596  			},
   597  		},
   598  		WriteRequest: structs.WriteRequest{Token: id},
   599  	}
   600  	var outR struct{}
   601  	if err := msgpackrpc.CallWithCodec(codec, "Catalog.Register", &argR, &outR); err != nil {
   602  		t.Fatalf("err: %v", err)
   603  	}
   604  
   605  	// First pass with version 8 ACL enforcement disabled, we should be able
   606  	// to deregister everything even without a token.
   607  	var err error
   608  	var out struct{}
   609  	err = msgpackrpc.CallWithCodec(codec, "Catalog.Deregister",
   610  		&structs.DeregisterRequest{
   611  			Datacenter: "dc1",
   612  			Node:       "node",
   613  			CheckID:    "service-check"}, &out)
   614  	if err != nil {
   615  		t.Fatalf("err: %v", err)
   616  	}
   617  	err = msgpackrpc.CallWithCodec(codec, "Catalog.Deregister",
   618  		&structs.DeregisterRequest{
   619  			Datacenter: "dc1",
   620  			Node:       "node",
   621  			CheckID:    "node-check"}, &out)
   622  	if err != nil {
   623  		t.Fatalf("err: %v", err)
   624  	}
   625  	err = msgpackrpc.CallWithCodec(codec, "Catalog.Deregister",
   626  		&structs.DeregisterRequest{
   627  			Datacenter: "dc1",
   628  			Node:       "node",
   629  			ServiceID:  "service"}, &out)
   630  	if err != nil {
   631  		t.Fatalf("err: %v", err)
   632  	}
   633  	err = msgpackrpc.CallWithCodec(codec, "Catalog.Deregister",
   634  		&structs.DeregisterRequest{
   635  			Datacenter: "dc1",
   636  			Node:       "node"}, &out)
   637  	if err != nil {
   638  		t.Fatalf("err: %v", err)
   639  	}
   640  
   641  	// Turn on version 8 ACL enforcement and put the catalog entry back.
   642  	s1.config.ACLEnforceVersion8 = true
   643  	if err := msgpackrpc.CallWithCodec(codec, "Catalog.Register", &argR, &outR); err != nil {
   644  		t.Fatalf("err: %v", err)
   645  	}
   646  
   647  	// Second pass with version 8 ACL enforcement enabled, these should all
   648  	// get rejected.
   649  	err = msgpackrpc.CallWithCodec(codec, "Catalog.Deregister",
   650  		&structs.DeregisterRequest{
   651  			Datacenter: "dc1",
   652  			Node:       "node",
   653  			CheckID:    "service-check"}, &out)
   654  	if !acl.IsErrPermissionDenied(err) {
   655  		t.Fatalf("err: %v", err)
   656  	}
   657  	err = msgpackrpc.CallWithCodec(codec, "Catalog.Deregister",
   658  		&structs.DeregisterRequest{
   659  			Datacenter: "dc1",
   660  			Node:       "node",
   661  			CheckID:    "node-check"}, &out)
   662  	if !acl.IsErrPermissionDenied(err) {
   663  		t.Fatalf("err: %v", err)
   664  	}
   665  	err = msgpackrpc.CallWithCodec(codec, "Catalog.Deregister",
   666  		&structs.DeregisterRequest{
   667  			Datacenter: "dc1",
   668  			Node:       "node",
   669  			ServiceID:  "service"}, &out)
   670  	if !acl.IsErrPermissionDenied(err) {
   671  		t.Fatalf("err: %v", err)
   672  	}
   673  	err = msgpackrpc.CallWithCodec(codec, "Catalog.Deregister",
   674  		&structs.DeregisterRequest{
   675  			Datacenter: "dc1",
   676  			Node:       "node"}, &out)
   677  	if !acl.IsErrPermissionDenied(err) {
   678  		t.Fatalf("err: %v", err)
   679  	}
   680  
   681  	// Third pass these should all go through with the token set.
   682  	err = msgpackrpc.CallWithCodec(codec, "Catalog.Deregister",
   683  		&structs.DeregisterRequest{
   684  			Datacenter: "dc1",
   685  			Node:       "node",
   686  			CheckID:    "service-check",
   687  			WriteRequest: structs.WriteRequest{
   688  				Token: id,
   689  			}}, &out)
   690  	if err != nil {
   691  		t.Fatalf("err: %v", err)
   692  	}
   693  	err = msgpackrpc.CallWithCodec(codec, "Catalog.Deregister",
   694  		&structs.DeregisterRequest{
   695  			Datacenter: "dc1",
   696  			Node:       "node",
   697  			CheckID:    "node-check",
   698  			WriteRequest: structs.WriteRequest{
   699  				Token: id,
   700  			}}, &out)
   701  	if err != nil {
   702  		t.Fatalf("err: %v", err)
   703  	}
   704  	err = msgpackrpc.CallWithCodec(codec, "Catalog.Deregister",
   705  		&structs.DeregisterRequest{
   706  			Datacenter: "dc1",
   707  			Node:       "node",
   708  			ServiceID:  "service",
   709  			WriteRequest: structs.WriteRequest{
   710  				Token: id,
   711  			}}, &out)
   712  	if err != nil {
   713  		t.Fatalf("err: %v", err)
   714  	}
   715  	err = msgpackrpc.CallWithCodec(codec, "Catalog.Deregister",
   716  		&structs.DeregisterRequest{
   717  			Datacenter: "dc1",
   718  			Node:       "node",
   719  			WriteRequest: structs.WriteRequest{
   720  				Token: id,
   721  			}}, &out)
   722  	if err != nil {
   723  		t.Fatalf("err: %v", err)
   724  	}
   725  
   726  	// Try a few error cases.
   727  	err = msgpackrpc.CallWithCodec(codec, "Catalog.Deregister",
   728  		&structs.DeregisterRequest{
   729  			Datacenter: "dc1",
   730  			Node:       "node",
   731  			ServiceID:  "nope",
   732  			WriteRequest: structs.WriteRequest{
   733  				Token: id,
   734  			}}, &out)
   735  	if err == nil || !strings.Contains(err.Error(), "Unknown service") {
   736  		t.Fatalf("err: %v", err)
   737  	}
   738  	err = msgpackrpc.CallWithCodec(codec, "Catalog.Deregister",
   739  		&structs.DeregisterRequest{
   740  			Datacenter: "dc1",
   741  			Node:       "node",
   742  			CheckID:    "nope",
   743  			WriteRequest: structs.WriteRequest{
   744  				Token: id,
   745  			}}, &out)
   746  	if err == nil || !strings.Contains(err.Error(), "Unknown check") {
   747  		t.Fatalf("err: %v", err)
   748  	}
   749  }
   750  
   751  func TestCatalog_ListDatacenters(t *testing.T) {
   752  	t.Parallel()
   753  	dir1, s1 := testServer(t)
   754  	defer os.RemoveAll(dir1)
   755  	defer s1.Shutdown()
   756  	codec := rpcClient(t, s1)
   757  	defer codec.Close()
   758  
   759  	dir2, s2 := testServerDC(t, "dc2")
   760  	defer os.RemoveAll(dir2)
   761  	defer s2.Shutdown()
   762  
   763  	// Try to join
   764  	joinWAN(t, s2, s1)
   765  
   766  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
   767  
   768  	var out []string
   769  	if err := msgpackrpc.CallWithCodec(codec, "Catalog.ListDatacenters", struct{}{}, &out); err != nil {
   770  		t.Fatalf("err: %v", err)
   771  	}
   772  
   773  	// The DCs should come out sorted by default.
   774  	if len(out) != 2 {
   775  		t.Fatalf("bad: %v", out)
   776  	}
   777  	if out[0] != "dc1" {
   778  		t.Fatalf("bad: %v", out)
   779  	}
   780  	if out[1] != "dc2" {
   781  		t.Fatalf("bad: %v", out)
   782  	}
   783  }
   784  
   785  func TestCatalog_ListDatacenters_DistanceSort(t *testing.T) {
   786  	t.Parallel()
   787  	dir1, s1 := testServer(t)
   788  	defer os.RemoveAll(dir1)
   789  	defer s1.Shutdown()
   790  	codec := rpcClient(t, s1)
   791  	defer codec.Close()
   792  
   793  	dir2, s2 := testServerDC(t, "dc2")
   794  	defer os.RemoveAll(dir2)
   795  	defer s2.Shutdown()
   796  
   797  	dir3, s3 := testServerDC(t, "acdc")
   798  	defer os.RemoveAll(dir3)
   799  	defer s3.Shutdown()
   800  
   801  	// Try to join
   802  	joinWAN(t, s2, s1)
   803  	joinWAN(t, s3, s1)
   804  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
   805  
   806  	var out []string
   807  	if err := msgpackrpc.CallWithCodec(codec, "Catalog.ListDatacenters", struct{}{}, &out); err != nil {
   808  		t.Fatalf("err: %v", err)
   809  	}
   810  
   811  	// It's super hard to force the Serfs into a known configuration of
   812  	// coordinates, so the best we can do is make sure that the sorting
   813  	// function is getting called (it's tested extensively in rtt_test.go).
   814  	// Since this is relative to dc1, it will be listed first (proving we
   815  	// went into the sort fn).
   816  	if len(out) != 3 {
   817  		t.Fatalf("bad: %v", out)
   818  	}
   819  	if out[0] != "dc1" {
   820  		t.Fatalf("bad: %v", out)
   821  	}
   822  }
   823  
   824  func TestCatalog_ListNodes(t *testing.T) {
   825  	t.Parallel()
   826  	dir1, s1 := testServer(t)
   827  	defer os.RemoveAll(dir1)
   828  	defer s1.Shutdown()
   829  	codec := rpcClient(t, s1)
   830  	defer codec.Close()
   831  
   832  	args := structs.DCSpecificRequest{
   833  		Datacenter: "dc1",
   834  	}
   835  	var out structs.IndexedNodes
   836  	err := msgpackrpc.CallWithCodec(codec, "Catalog.ListNodes", &args, &out)
   837  	if err != nil {
   838  		t.Fatalf("err: %v", err)
   839  	}
   840  
   841  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
   842  
   843  	// Just add a node
   844  	if err := s1.fsm.State().EnsureNode(1, &structs.Node{Node: "foo", Address: "127.0.0.1"}); err != nil {
   845  		t.Fatalf("err: %v", err)
   846  	}
   847  	retry.Run(t, func(r *retry.R) {
   848  		msgpackrpc.CallWithCodec(codec, "Catalog.ListNodes", &args, &out)
   849  		if got, want := len(out.Nodes), 2; got != want {
   850  			r.Fatalf("got %d nodes want %d", got, want)
   851  		}
   852  	})
   853  
   854  	// Server node is auto added from Serf
   855  	if out.Nodes[1].Node != s1.config.NodeName {
   856  		t.Fatalf("bad: %v", out)
   857  	}
   858  	if out.Nodes[0].Node != "foo" {
   859  		t.Fatalf("bad: %v", out)
   860  	}
   861  	if out.Nodes[0].Address != "127.0.0.1" {
   862  		t.Fatalf("bad: %v", out)
   863  	}
   864  }
   865  
   866  func TestCatalog_ListNodes_NodeMetaFilter(t *testing.T) {
   867  	t.Parallel()
   868  	dir1, s1 := testServer(t)
   869  	defer os.RemoveAll(dir1)
   870  	defer s1.Shutdown()
   871  	codec := rpcClient(t, s1)
   872  	defer codec.Close()
   873  
   874  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
   875  
   876  	// Add a new node with the right meta k/v pair
   877  	node := &structs.Node{Node: "foo", Address: "127.0.0.1", Meta: map[string]string{"somekey": "somevalue"}}
   878  	if err := s1.fsm.State().EnsureNode(1, node); err != nil {
   879  		t.Fatalf("err: %v", err)
   880  	}
   881  
   882  	// Filter by a specific meta k/v pair
   883  	args := structs.DCSpecificRequest{
   884  		Datacenter: "dc1",
   885  		NodeMetaFilters: map[string]string{
   886  			"somekey": "somevalue",
   887  		},
   888  	}
   889  	var out structs.IndexedNodes
   890  	retry.Run(t, func(r *retry.R) {
   891  		msgpackrpc.CallWithCodec(codec, "Catalog.ListNodes", &args, &out)
   892  		if got, want := len(out.Nodes), 1; got != want {
   893  			r.Fatalf("got %d nodes want %d", got, want)
   894  		}
   895  	})
   896  
   897  	// Verify that only the correct node was returned
   898  	if out.Nodes[0].Node != "foo" {
   899  		t.Fatalf("bad: %v", out)
   900  	}
   901  	if out.Nodes[0].Address != "127.0.0.1" {
   902  		t.Fatalf("bad: %v", out)
   903  	}
   904  	if v, ok := out.Nodes[0].Meta["somekey"]; !ok || v != "somevalue" {
   905  		t.Fatalf("bad: %v", out)
   906  	}
   907  
   908  	// Now filter on a nonexistent meta k/v pair
   909  	args = structs.DCSpecificRequest{
   910  		Datacenter: "dc1",
   911  		NodeMetaFilters: map[string]string{
   912  			"somekey": "invalid",
   913  		},
   914  	}
   915  	out = structs.IndexedNodes{}
   916  	err := msgpackrpc.CallWithCodec(codec, "Catalog.ListNodes", &args, &out)
   917  	if err != nil {
   918  		t.Fatalf("err: %v", err)
   919  	}
   920  	// Should get an empty list of nodes back
   921  	retry.Run(t, func(r *retry.R) {
   922  		msgpackrpc.CallWithCodec(codec, "Catalog.ListNodes", &args, &out)
   923  		if len(out.Nodes) != 0 {
   924  			r.Fatal(nil)
   925  		}
   926  	})
   927  }
   928  
   929  func TestCatalog_ListNodes_StaleRead(t *testing.T) {
   930  	t.Parallel()
   931  	dir1, s1 := testServer(t)
   932  	defer os.RemoveAll(dir1)
   933  	defer s1.Shutdown()
   934  	codec1 := rpcClient(t, s1)
   935  	defer codec1.Close()
   936  	testrpc.WaitForTestAgent(t, s1.RPC, "dc1")
   937  
   938  	dir2, s2 := testServerDCBootstrap(t, "dc1", false)
   939  	defer os.RemoveAll(dir2)
   940  	defer s2.Shutdown()
   941  	codec2 := rpcClient(t, s2)
   942  	defer codec2.Close()
   943  
   944  	// Try to join
   945  	joinLAN(t, s2, s1)
   946  
   947  	testrpc.WaitForTestAgent(t, s1.RPC, "dc1")
   948  	testrpc.WaitForTestAgent(t, s2.RPC, "dc1")
   949  
   950  	// Use the follower as the client
   951  	var codec rpc.ClientCodec
   952  	if !s1.IsLeader() {
   953  		codec = codec1
   954  
   955  		// Inject fake data on the follower!
   956  		if err := s1.fsm.State().EnsureNode(1, &structs.Node{Node: "foo", Address: "127.0.0.1"}); err != nil {
   957  			t.Fatalf("err: %v", err)
   958  		}
   959  	} else {
   960  		codec = codec2
   961  
   962  		// Inject fake data on the follower!
   963  		if err := s2.fsm.State().EnsureNode(1, &structs.Node{Node: "foo", Address: "127.0.0.1"}); err != nil {
   964  			t.Fatalf("err: %v", err)
   965  		}
   966  	}
   967  
   968  	args := structs.DCSpecificRequest{
   969  		Datacenter:   "dc1",
   970  		QueryOptions: structs.QueryOptions{AllowStale: true},
   971  	}
   972  	var out structs.IndexedNodes
   973  	if err := msgpackrpc.CallWithCodec(codec, "Catalog.ListNodes", &args, &out); err != nil {
   974  		t.Fatalf("err: %v", err)
   975  	}
   976  
   977  	found := false
   978  	for _, n := range out.Nodes {
   979  		if n.Node == "foo" {
   980  			found = true
   981  		}
   982  	}
   983  	if !found {
   984  		t.Fatalf("failed to find foo in %#v", out.Nodes)
   985  	}
   986  
   987  	if out.QueryMeta.LastContact == 0 {
   988  		t.Fatalf("should have a last contact time")
   989  	}
   990  	if !out.QueryMeta.KnownLeader {
   991  		t.Fatalf("should have known leader")
   992  	}
   993  }
   994  
   995  func TestCatalog_ListNodes_ConsistentRead_Fail(t *testing.T) {
   996  	t.Parallel()
   997  	dir1, s1 := testServer(t)
   998  	defer os.RemoveAll(dir1)
   999  	defer s1.Shutdown()
  1000  
  1001  	dir2, s2 := testServerDCBootstrap(t, "dc1", false)
  1002  	defer os.RemoveAll(dir2)
  1003  	defer s2.Shutdown()
  1004  
  1005  	dir3, s3 := testServerDCBootstrap(t, "dc1", false)
  1006  	defer os.RemoveAll(dir3)
  1007  	defer s3.Shutdown()
  1008  
  1009  	// Try to join and wait for all servers to get promoted to voters.
  1010  	joinLAN(t, s2, s1)
  1011  	joinLAN(t, s3, s2)
  1012  	servers := []*Server{s1, s2, s3}
  1013  	retry.Run(t, func(r *retry.R) {
  1014  		r.Check(wantRaft(servers))
  1015  		for _, s := range servers {
  1016  			r.Check(wantPeers(s, 3))
  1017  		}
  1018  	})
  1019  
  1020  	// Use the leader as the client, kill the followers.
  1021  	var codec rpc.ClientCodec
  1022  	for _, s := range servers {
  1023  		if s.IsLeader() {
  1024  			codec = rpcClient(t, s)
  1025  			defer codec.Close()
  1026  		} else {
  1027  			s.Shutdown()
  1028  		}
  1029  	}
  1030  	if codec == nil {
  1031  		t.Fatalf("no leader")
  1032  	}
  1033  
  1034  	args := structs.DCSpecificRequest{
  1035  		Datacenter:   "dc1",
  1036  		QueryOptions: structs.QueryOptions{RequireConsistent: true},
  1037  	}
  1038  	var out structs.IndexedNodes
  1039  	err := msgpackrpc.CallWithCodec(codec, "Catalog.ListNodes", &args, &out)
  1040  	if err == nil || !strings.HasPrefix(err.Error(), "leadership lost") {
  1041  		t.Fatalf("err: %v", err)
  1042  	}
  1043  	if out.QueryMeta.LastContact != 0 {
  1044  		t.Fatalf("should not have a last contact time")
  1045  	}
  1046  	if out.QueryMeta.KnownLeader {
  1047  		t.Fatalf("should have no known leader")
  1048  	}
  1049  }
  1050  
  1051  func TestCatalog_ListNodes_ConsistentRead(t *testing.T) {
  1052  	t.Parallel()
  1053  	dir1, s1 := testServer(t)
  1054  	defer os.RemoveAll(dir1)
  1055  	defer s1.Shutdown()
  1056  	codec1 := rpcClient(t, s1)
  1057  	defer codec1.Close()
  1058  
  1059  	dir2, s2 := testServerDCBootstrap(t, "dc1", false)
  1060  	defer os.RemoveAll(dir2)
  1061  	defer s2.Shutdown()
  1062  	codec2 := rpcClient(t, s2)
  1063  	defer codec2.Close()
  1064  
  1065  	// Try to join
  1066  	joinLAN(t, s2, s1)
  1067  
  1068  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
  1069  	testrpc.WaitForLeader(t, s2.RPC, "dc1")
  1070  
  1071  	// Use the leader as the client, kill the follower
  1072  	var codec rpc.ClientCodec
  1073  	if s1.IsLeader() {
  1074  		codec = codec1
  1075  	} else {
  1076  		codec = codec2
  1077  	}
  1078  
  1079  	args := structs.DCSpecificRequest{
  1080  		Datacenter:   "dc1",
  1081  		QueryOptions: structs.QueryOptions{RequireConsistent: true},
  1082  	}
  1083  	var out structs.IndexedNodes
  1084  	if err := msgpackrpc.CallWithCodec(codec, "Catalog.ListNodes", &args, &out); err != nil {
  1085  		t.Fatalf("err: %v", err)
  1086  	}
  1087  
  1088  	if out.QueryMeta.LastContact != 0 {
  1089  		t.Fatalf("should not have a last contact time")
  1090  	}
  1091  	if !out.QueryMeta.KnownLeader {
  1092  		t.Fatalf("should have known leader")
  1093  	}
  1094  }
  1095  
  1096  func TestCatalog_ListNodes_DistanceSort(t *testing.T) {
  1097  	t.Parallel()
  1098  	dir1, s1 := testServer(t)
  1099  	defer os.RemoveAll(dir1)
  1100  	defer s1.Shutdown()
  1101  	codec := rpcClient(t, s1)
  1102  	defer codec.Close()
  1103  
  1104  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
  1105  	if err := s1.fsm.State().EnsureNode(1, &structs.Node{Node: "aaa", Address: "127.0.0.1"}); err != nil {
  1106  		t.Fatalf("err: %v", err)
  1107  	}
  1108  	if err := s1.fsm.State().EnsureNode(2, &structs.Node{Node: "foo", Address: "127.0.0.2"}); err != nil {
  1109  		t.Fatalf("err: %v", err)
  1110  	}
  1111  	if err := s1.fsm.State().EnsureNode(3, &structs.Node{Node: "bar", Address: "127.0.0.3"}); err != nil {
  1112  		t.Fatalf("err: %v", err)
  1113  	}
  1114  	if err := s1.fsm.State().EnsureNode(4, &structs.Node{Node: "baz", Address: "127.0.0.4"}); err != nil {
  1115  		t.Fatalf("err: %v", err)
  1116  	}
  1117  
  1118  	// Set all but one of the nodes to known coordinates.
  1119  	updates := structs.Coordinates{
  1120  		{Node: "foo", Coord: lib.GenerateCoordinate(2 * time.Millisecond)},
  1121  		{Node: "bar", Coord: lib.GenerateCoordinate(5 * time.Millisecond)},
  1122  		{Node: "baz", Coord: lib.GenerateCoordinate(1 * time.Millisecond)},
  1123  	}
  1124  	if err := s1.fsm.State().CoordinateBatchUpdate(5, updates); err != nil {
  1125  		t.Fatalf("err: %v", err)
  1126  	}
  1127  
  1128  	// Query with no given source node, should get the natural order from
  1129  	// the index.
  1130  	args := structs.DCSpecificRequest{
  1131  		Datacenter: "dc1",
  1132  	}
  1133  	var out structs.IndexedNodes
  1134  	retry.Run(t, func(r *retry.R) {
  1135  		msgpackrpc.CallWithCodec(codec, "Catalog.ListNodes", &args, &out)
  1136  		if got, want := len(out.Nodes), 5; got != want {
  1137  			r.Fatalf("got %d nodes want %d", got, want)
  1138  		}
  1139  	})
  1140  
  1141  	if out.Nodes[0].Node != "aaa" {
  1142  		t.Fatalf("bad: %v", out)
  1143  	}
  1144  	if out.Nodes[1].Node != "bar" {
  1145  		t.Fatalf("bad: %v", out)
  1146  	}
  1147  	if out.Nodes[2].Node != "baz" {
  1148  		t.Fatalf("bad: %v", out)
  1149  	}
  1150  	if out.Nodes[3].Node != "foo" {
  1151  		t.Fatalf("bad: %v", out)
  1152  	}
  1153  	if out.Nodes[4].Node != s1.config.NodeName {
  1154  		t.Fatalf("bad: %v", out)
  1155  	}
  1156  
  1157  	// Query relative to foo, note that there's no known coordinate for the
  1158  	// default-added Serf node nor "aaa" so they will go at the end.
  1159  	args = structs.DCSpecificRequest{
  1160  		Datacenter: "dc1",
  1161  		Source:     structs.QuerySource{Datacenter: "dc1", Node: "foo"},
  1162  	}
  1163  	retry.Run(t, func(r *retry.R) {
  1164  		msgpackrpc.CallWithCodec(codec, "Catalog.ListNodes", &args, &out)
  1165  		if got, want := len(out.Nodes), 5; got != want {
  1166  			r.Fatalf("got %d nodes want %d", got, want)
  1167  		}
  1168  	})
  1169  
  1170  	if out.Nodes[0].Node != "foo" {
  1171  		t.Fatalf("bad: %v", out)
  1172  	}
  1173  	if out.Nodes[1].Node != "baz" {
  1174  		t.Fatalf("bad: %v", out)
  1175  	}
  1176  	if out.Nodes[2].Node != "bar" {
  1177  		t.Fatalf("bad: %v", out)
  1178  	}
  1179  	if out.Nodes[3].Node != "aaa" {
  1180  		t.Fatalf("bad: %v", out)
  1181  	}
  1182  	if out.Nodes[4].Node != s1.config.NodeName {
  1183  		t.Fatalf("bad: %v", out)
  1184  	}
  1185  }
  1186  
  1187  func TestCatalog_ListNodes_ACLFilter(t *testing.T) {
  1188  	t.Parallel()
  1189  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
  1190  		c.ACLDatacenter = "dc1"
  1191  		c.ACLsEnabled = true
  1192  		c.ACLMasterToken = "root"
  1193  		c.ACLDefaultPolicy = "deny"
  1194  		c.ACLEnforceVersion8 = false
  1195  	})
  1196  	defer os.RemoveAll(dir1)
  1197  	defer s1.Shutdown()
  1198  	codec := rpcClient(t, s1)
  1199  	defer codec.Close()
  1200  
  1201  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
  1202  
  1203  	// We scope the reply in each of these since msgpack won't clear out an
  1204  	// existing slice if the incoming one is nil, so it's best to start
  1205  	// clean each time.
  1206  
  1207  	// Prior to version 8, the node policy should be ignored.
  1208  	args := structs.DCSpecificRequest{
  1209  		Datacenter: "dc1",
  1210  	}
  1211  	{
  1212  		reply := structs.IndexedNodes{}
  1213  		if err := msgpackrpc.CallWithCodec(codec, "Catalog.ListNodes", &args, &reply); err != nil {
  1214  			t.Fatalf("err: %v", err)
  1215  		}
  1216  		if len(reply.Nodes) != 1 {
  1217  			t.Fatalf("bad: %v", reply.Nodes)
  1218  		}
  1219  	}
  1220  
  1221  	// Now turn on version 8 enforcement and try again.
  1222  	s1.config.ACLEnforceVersion8 = true
  1223  	{
  1224  		reply := structs.IndexedNodes{}
  1225  		if err := msgpackrpc.CallWithCodec(codec, "Catalog.ListNodes", &args, &reply); err != nil {
  1226  			t.Fatalf("err: %v", err)
  1227  		}
  1228  		if len(reply.Nodes) != 0 {
  1229  			t.Fatalf("bad: %v", reply.Nodes)
  1230  		}
  1231  	}
  1232  
  1233  	// Create an ACL that can read the node.
  1234  	arg := structs.ACLRequest{
  1235  		Datacenter: "dc1",
  1236  		Op:         structs.ACLSet,
  1237  		ACL: structs.ACL{
  1238  			Name: "User token",
  1239  			Type: structs.ACLTokenTypeClient,
  1240  			Rules: fmt.Sprintf(`
  1241  node "%s" {
  1242  	policy = "read"
  1243  }
  1244  `, s1.config.NodeName),
  1245  		},
  1246  		WriteRequest: structs.WriteRequest{Token: "root"},
  1247  	}
  1248  	var id string
  1249  	if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &arg, &id); err != nil {
  1250  		t.Fatalf("err: %v", err)
  1251  	}
  1252  
  1253  	// Now try with the token and it will go through.
  1254  	args.Token = id
  1255  	{
  1256  		reply := structs.IndexedNodes{}
  1257  		if err := msgpackrpc.CallWithCodec(codec, "Catalog.ListNodes", &args, &reply); err != nil {
  1258  			t.Fatalf("err: %v", err)
  1259  		}
  1260  		if len(reply.Nodes) != 1 {
  1261  			t.Fatalf("bad: %v", reply.Nodes)
  1262  		}
  1263  	}
  1264  }
  1265  
  1266  func Benchmark_Catalog_ListNodes(t *testing.B) {
  1267  	dir1, s1 := testServer(nil)
  1268  	defer os.RemoveAll(dir1)
  1269  	defer s1.Shutdown()
  1270  	codec := rpcClient(nil, s1)
  1271  	defer codec.Close()
  1272  
  1273  	// Just add a node
  1274  	if err := s1.fsm.State().EnsureNode(1, &structs.Node{Node: "foo", Address: "127.0.0.1"}); err != nil {
  1275  		t.Fatalf("err: %v", err)
  1276  	}
  1277  
  1278  	args := structs.DCSpecificRequest{
  1279  		Datacenter: "dc1",
  1280  	}
  1281  	for i := 0; i < t.N; i++ {
  1282  		var out structs.IndexedNodes
  1283  		if err := msgpackrpc.CallWithCodec(codec, "Catalog.ListNodes", &args, &out); err != nil {
  1284  			t.Fatalf("err: %v", err)
  1285  		}
  1286  	}
  1287  }
  1288  
  1289  func TestCatalog_ListServices(t *testing.T) {
  1290  	t.Parallel()
  1291  	dir1, s1 := testServer(t)
  1292  	defer os.RemoveAll(dir1)
  1293  	defer s1.Shutdown()
  1294  	codec := rpcClient(t, s1)
  1295  	defer codec.Close()
  1296  
  1297  	args := structs.DCSpecificRequest{
  1298  		Datacenter: "dc1",
  1299  	}
  1300  	var out structs.IndexedServices
  1301  	err := msgpackrpc.CallWithCodec(codec, "Catalog.ListServices", &args, &out)
  1302  	if err != nil {
  1303  		t.Fatalf("err: %v", err)
  1304  	}
  1305  
  1306  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
  1307  
  1308  	// Just add a node
  1309  	if err := s1.fsm.State().EnsureNode(1, &structs.Node{Node: "foo", Address: "127.0.0.1"}); err != nil {
  1310  		t.Fatalf("err: %v", err)
  1311  	}
  1312  	if err := s1.fsm.State().EnsureService(2, "foo", &structs.NodeService{ID: "db", Service: "db", Tags: []string{"primary"}, Address: "127.0.0.1", Port: 5000}); err != nil {
  1313  		t.Fatalf("err: %v", err)
  1314  	}
  1315  
  1316  	if err := msgpackrpc.CallWithCodec(codec, "Catalog.ListServices", &args, &out); err != nil {
  1317  		t.Fatalf("err: %v", err)
  1318  	}
  1319  
  1320  	if len(out.Services) != 2 {
  1321  		t.Fatalf("bad: %v", out)
  1322  	}
  1323  	for _, s := range out.Services {
  1324  		if s == nil {
  1325  			t.Fatalf("bad: %v", s)
  1326  		}
  1327  	}
  1328  	// Consul service should auto-register
  1329  	if _, ok := out.Services["consul"]; !ok {
  1330  		t.Fatalf("bad: %v", out)
  1331  	}
  1332  	if len(out.Services["db"]) != 1 {
  1333  		t.Fatalf("bad: %v", out)
  1334  	}
  1335  	if out.Services["db"][0] != "primary" {
  1336  		t.Fatalf("bad: %v", out)
  1337  	}
  1338  }
  1339  
  1340  func TestCatalog_ListServices_NodeMetaFilter(t *testing.T) {
  1341  	t.Parallel()
  1342  	dir1, s1 := testServer(t)
  1343  	defer os.RemoveAll(dir1)
  1344  	defer s1.Shutdown()
  1345  	codec := rpcClient(t, s1)
  1346  	defer codec.Close()
  1347  
  1348  	testrpc.WaitForTestAgent(t, s1.RPC, "dc1")
  1349  
  1350  	// Add a new node with the right meta k/v pair
  1351  	node := &structs.Node{Node: "foo", Address: "127.0.0.1", Meta: map[string]string{"somekey": "somevalue"}}
  1352  	if err := s1.fsm.State().EnsureNode(1, node); err != nil {
  1353  		t.Fatalf("err: %v", err)
  1354  	}
  1355  	// Add a service to the new node
  1356  	if err := s1.fsm.State().EnsureService(2, "foo", &structs.NodeService{ID: "db", Service: "db", Tags: []string{"primary"}, Address: "127.0.0.1", Port: 5000}); err != nil {
  1357  		t.Fatalf("err: %v", err)
  1358  	}
  1359  
  1360  	// Filter by a specific meta k/v pair
  1361  	args := structs.DCSpecificRequest{
  1362  		Datacenter: "dc1",
  1363  		NodeMetaFilters: map[string]string{
  1364  			"somekey": "somevalue",
  1365  		},
  1366  	}
  1367  	var out structs.IndexedServices
  1368  	if err := msgpackrpc.CallWithCodec(codec, "Catalog.ListServices", &args, &out); err != nil {
  1369  		t.Fatalf("err: %v", err)
  1370  	}
  1371  
  1372  	if len(out.Services) != 1 {
  1373  		t.Fatalf("bad: %v", out)
  1374  	}
  1375  	if out.Services["db"] == nil {
  1376  		t.Fatalf("bad: %v", out.Services["db"])
  1377  	}
  1378  	if len(out.Services["db"]) != 1 {
  1379  		t.Fatalf("bad: %v", out)
  1380  	}
  1381  	if out.Services["db"][0] != "primary" {
  1382  		t.Fatalf("bad: %v", out)
  1383  	}
  1384  
  1385  	// Now filter on a nonexistent meta k/v pair
  1386  	args = structs.DCSpecificRequest{
  1387  		Datacenter: "dc1",
  1388  		NodeMetaFilters: map[string]string{
  1389  			"somekey": "invalid",
  1390  		},
  1391  	}
  1392  	out = structs.IndexedServices{}
  1393  	err := msgpackrpc.CallWithCodec(codec, "Catalog.ListServices", &args, &out)
  1394  	if err != nil {
  1395  		t.Fatalf("err: %v", err)
  1396  	}
  1397  
  1398  	// Should get an empty list of nodes back
  1399  	if len(out.Services) != 0 {
  1400  		t.Fatalf("bad: %v", out.Services)
  1401  	}
  1402  }
  1403  
  1404  func TestCatalog_ListServices_Blocking(t *testing.T) {
  1405  	t.Parallel()
  1406  	dir1, s1 := testServer(t)
  1407  	defer os.RemoveAll(dir1)
  1408  	defer s1.Shutdown()
  1409  	codec := rpcClient(t, s1)
  1410  	defer codec.Close()
  1411  
  1412  	args := structs.DCSpecificRequest{
  1413  		Datacenter: "dc1",
  1414  	}
  1415  	var out structs.IndexedServices
  1416  
  1417  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
  1418  
  1419  	// Run the query
  1420  	if err := msgpackrpc.CallWithCodec(codec, "Catalog.ListServices", &args, &out); err != nil {
  1421  		t.Fatalf("err: %v", err)
  1422  	}
  1423  
  1424  	// Setup a blocking query
  1425  	args.MinQueryIndex = out.Index
  1426  	args.MaxQueryTime = time.Second
  1427  
  1428  	// Async cause a change
  1429  	idx := out.Index
  1430  	start := time.Now()
  1431  	go func() {
  1432  		time.Sleep(100 * time.Millisecond)
  1433  		if err := s1.fsm.State().EnsureNode(idx+1, &structs.Node{Node: "foo", Address: "127.0.0.1"}); err != nil {
  1434  			t.Fatalf("err: %v", err)
  1435  		}
  1436  		if err := s1.fsm.State().EnsureService(idx+2, "foo", &structs.NodeService{ID: "db", Service: "db", Tags: []string{"primary"}, Address: "127.0.0.1", Port: 5000}); err != nil {
  1437  			t.Fatalf("err: %v", err)
  1438  		}
  1439  	}()
  1440  
  1441  	// Re-run the query
  1442  	out = structs.IndexedServices{}
  1443  	if err := msgpackrpc.CallWithCodec(codec, "Catalog.ListServices", &args, &out); err != nil {
  1444  		t.Fatalf("err: %v", err)
  1445  	}
  1446  
  1447  	// Should block at least 100ms
  1448  	if time.Since(start) < 100*time.Millisecond {
  1449  		t.Fatalf("too fast")
  1450  	}
  1451  
  1452  	// Check the indexes
  1453  	if out.Index != idx+2 {
  1454  		t.Fatalf("bad: %v", out)
  1455  	}
  1456  
  1457  	// Should find the service
  1458  	if len(out.Services) != 2 {
  1459  		t.Fatalf("bad: %v", out)
  1460  	}
  1461  }
  1462  
  1463  func TestCatalog_ListServices_Timeout(t *testing.T) {
  1464  	t.Parallel()
  1465  	dir1, s1 := testServer(t)
  1466  	defer os.RemoveAll(dir1)
  1467  	defer s1.Shutdown()
  1468  	codec := rpcClient(t, s1)
  1469  	defer codec.Close()
  1470  
  1471  	args := structs.DCSpecificRequest{
  1472  		Datacenter: "dc1",
  1473  	}
  1474  	var out structs.IndexedServices
  1475  
  1476  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
  1477  
  1478  	// Run the query
  1479  	if err := msgpackrpc.CallWithCodec(codec, "Catalog.ListServices", &args, &out); err != nil {
  1480  		t.Fatalf("err: %v", err)
  1481  	}
  1482  
  1483  	// Setup a blocking query
  1484  	args.MinQueryIndex = out.Index
  1485  	args.MaxQueryTime = 100 * time.Millisecond
  1486  
  1487  	// Re-run the query
  1488  	start := time.Now()
  1489  	out = structs.IndexedServices{}
  1490  	if err := msgpackrpc.CallWithCodec(codec, "Catalog.ListServices", &args, &out); err != nil {
  1491  		t.Fatalf("err: %v", err)
  1492  	}
  1493  
  1494  	// Should block at least 100ms
  1495  	if time.Since(start) < 100*time.Millisecond {
  1496  		t.Fatalf("too fast")
  1497  	}
  1498  
  1499  	// Check the indexes, should not change
  1500  	if out.Index != args.MinQueryIndex {
  1501  		t.Fatalf("bad: %v", out)
  1502  	}
  1503  }
  1504  
  1505  func TestCatalog_ListServices_Stale(t *testing.T) {
  1506  	t.Parallel()
  1507  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
  1508  		c.ACLDatacenter = "dc1"
  1509  		c.ACLsEnabled = true
  1510  	})
  1511  	defer os.RemoveAll(dir1)
  1512  	defer s1.Shutdown()
  1513  
  1514  	testrpc.WaitForTestAgent(t, s1.RPC, "dc1")
  1515  	dir2, s2 := testServerWithConfig(t, func(c *Config) {
  1516  		c.ACLDatacenter = "dc1" // Enable ACLs!
  1517  		c.ACLsEnabled = true
  1518  		c.Bootstrap = false // Disable bootstrap
  1519  	})
  1520  	defer os.RemoveAll(dir2)
  1521  	defer s2.Shutdown()
  1522  
  1523  	args := structs.DCSpecificRequest{
  1524  		Datacenter: "dc1",
  1525  	}
  1526  	args.AllowStale = true
  1527  	var out structs.IndexedServices
  1528  
  1529  	// Inject a node
  1530  	if err := s1.fsm.State().EnsureNode(3, &structs.Node{Node: "foo", Address: "127.0.0.1"}); err != nil {
  1531  		t.Fatalf("err: %v", err)
  1532  	}
  1533  
  1534  	codec := rpcClient(t, s2)
  1535  	defer codec.Close()
  1536  
  1537  	// Run the query, do not wait for leader, never any contact with leader, should fail
  1538  	if err := msgpackrpc.CallWithCodec(codec, "Catalog.ListServices", &args, &out); err == nil || err.Error() != structs.ErrNoLeader.Error() {
  1539  		t.Fatalf("expected %v but got err: %v and %v", structs.ErrNoLeader, err, out)
  1540  	}
  1541  
  1542  	// Try to join
  1543  	joinLAN(t, s2, s1)
  1544  	retry.Run(t, func(r *retry.R) { r.Check(wantRaft([]*Server{s1, s2})) })
  1545  	waitForLeader(s1, s2)
  1546  
  1547  	testrpc.WaitForLeader(t, s2.RPC, "dc1")
  1548  	if err := msgpackrpc.CallWithCodec(codec, "Catalog.ListServices", &args, &out); err != nil {
  1549  		t.Fatalf("err: %v", err)
  1550  	}
  1551  
  1552  	// Should find the services
  1553  	if len(out.Services) != 1 {
  1554  		t.Fatalf("bad: %#v", out.Services)
  1555  	}
  1556  
  1557  	if !out.KnownLeader {
  1558  		t.Fatalf("should have a leader: %v", out)
  1559  	}
  1560  
  1561  	s1.Leave()
  1562  	s1.Shutdown()
  1563  
  1564  	testrpc.WaitUntilNoLeader(t, s2.RPC, "dc1")
  1565  
  1566  	args.AllowStale = false
  1567  	// Since the leader is now down, non-stale query should fail now
  1568  	if err := msgpackrpc.CallWithCodec(codec, "Catalog.ListServices", &args, &out); err == nil || err.Error() != structs.ErrNoLeader.Error() {
  1569  		t.Fatalf("expected %v but got err: %v and %v", structs.ErrNoLeader, err, out)
  1570  	}
  1571  
  1572  	// With stale, request should still work
  1573  	args.AllowStale = true
  1574  	if err := msgpackrpc.CallWithCodec(codec, "Catalog.ListServices", &args, &out); err != nil {
  1575  		t.Fatalf("err: %v", err)
  1576  	}
  1577  
  1578  	// Should find old service
  1579  	if len(out.Services) != 1 {
  1580  		t.Fatalf("bad: %#v", out)
  1581  	}
  1582  
  1583  	if out.KnownLeader {
  1584  		t.Fatalf("should not have a leader anymore: %#v", out)
  1585  	}
  1586  }
  1587  
  1588  func TestCatalog_ListServiceNodes(t *testing.T) {
  1589  	t.Parallel()
  1590  	dir1, s1 := testServer(t)
  1591  	defer os.RemoveAll(dir1)
  1592  	defer s1.Shutdown()
  1593  	codec := rpcClient(t, s1)
  1594  	defer codec.Close()
  1595  
  1596  	args := structs.ServiceSpecificRequest{
  1597  		Datacenter:  "dc1",
  1598  		ServiceName: "db",
  1599  		ServiceTags: []string{"slave"},
  1600  		TagFilter:   false,
  1601  	}
  1602  	var out structs.IndexedServiceNodes
  1603  	err := msgpackrpc.CallWithCodec(codec, "Catalog.ServiceNodes", &args, &out)
  1604  	if err != nil {
  1605  		t.Fatalf("err: %v", err)
  1606  	}
  1607  
  1608  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
  1609  
  1610  	// Just add a node
  1611  	if err := s1.fsm.State().EnsureNode(1, &structs.Node{Node: "foo", Address: "127.0.0.1"}); err != nil {
  1612  		t.Fatalf("err: %v", err)
  1613  	}
  1614  	if err := s1.fsm.State().EnsureService(2, "foo", &structs.NodeService{ID: "db", Service: "db", Tags: []string{"primary"}, Address: "127.0.0.1", Port: 5000}); err != nil {
  1615  		t.Fatalf("err: %v", err)
  1616  	}
  1617  
  1618  	if err := msgpackrpc.CallWithCodec(codec, "Catalog.ServiceNodes", &args, &out); err != nil {
  1619  		t.Fatalf("err: %v", err)
  1620  	}
  1621  
  1622  	if len(out.ServiceNodes) != 1 {
  1623  		t.Fatalf("bad: %v", out)
  1624  	}
  1625  
  1626  	// Try with a filter
  1627  	args.TagFilter = true
  1628  	out = structs.IndexedServiceNodes{}
  1629  
  1630  	if err := msgpackrpc.CallWithCodec(codec, "Catalog.ServiceNodes", &args, &out); err != nil {
  1631  		t.Fatalf("err: %v", err)
  1632  	}
  1633  	if len(out.ServiceNodes) != 0 {
  1634  		t.Fatalf("bad: %v", out)
  1635  	}
  1636  }
  1637  
  1638  // TestCatalog_ListServiceNodes_ServiceTags_V1_2_3Compat asserts the compatibility between <=v1.2.3 agents and >=v1.3.0 servers
  1639  // see https://github.com/hashicorp/consul/issues/4922
  1640  func TestCatalog_ListServiceNodes_ServiceTags_V1_2_3Compat(t *testing.T) {
  1641  	t.Parallel()
  1642  	dir1, s1 := testServer(t)
  1643  	defer os.RemoveAll(dir1)
  1644  	defer s1.Shutdown()
  1645  	codec := rpcClient(t, s1)
  1646  	defer codec.Close()
  1647  
  1648  	testrpc.WaitForTestAgent(t, s1.RPC, "dc1")
  1649  
  1650  	err := s1.fsm.State().EnsureNode(1, &structs.Node{Node: "foo", Address: "127.0.0.1"})
  1651  	require.NoError(t, err)
  1652  
  1653  	// register two service instances with different tags
  1654  	err = s1.fsm.State().EnsureService(2, "foo", &structs.NodeService{ID: "db1", Service: "db", Tags: []string{"primary"}, Address: "127.0.0.1", Port: 5000})
  1655  	require.NoError(t, err)
  1656  	err = s1.fsm.State().EnsureService(2, "foo", &structs.NodeService{ID: "db2", Service: "db", Tags: []string{"secondary"}, Address: "127.0.0.1", Port: 5001})
  1657  	require.NoError(t, err)
  1658  
  1659  	// DEPRECATED (singular-service-tag) - remove this when backwards RPC compat
  1660  	// with 1.2.x is not required.
  1661  	// make a request with the <=1.2.3 ServiceTag tag field (vs ServiceTags)
  1662  	args := structs.ServiceSpecificRequest{
  1663  		Datacenter:  "dc1",
  1664  		ServiceName: "db",
  1665  		ServiceTag:  "primary",
  1666  		TagFilter:   true,
  1667  	}
  1668  	var out structs.IndexedServiceNodes
  1669  	err = msgpackrpc.CallWithCodec(codec, "Catalog.ServiceNodes", &args, &out)
  1670  	require.NoError(t, err)
  1671  
  1672  	// nodes should be filtered, even when using the old ServiceTag field
  1673  	require.Equal(t, 1, len(out.ServiceNodes))
  1674  	require.Equal(t, "db1", out.ServiceNodes[0].ServiceID)
  1675  
  1676  	// DEPRECATED (singular-service-tag) - remove this when backwards RPC compat
  1677  	// with 1.2.x is not required.
  1678  	// test with the other tag
  1679  	args = structs.ServiceSpecificRequest{
  1680  		Datacenter:  "dc1",
  1681  		ServiceName: "db",
  1682  		ServiceTag:  "secondary",
  1683  		TagFilter:   true,
  1684  	}
  1685  	out = structs.IndexedServiceNodes{}
  1686  	err = msgpackrpc.CallWithCodec(codec, "Catalog.ServiceNodes", &args, &out)
  1687  	require.NoError(t, err)
  1688  	require.Equal(t, 1, len(out.ServiceNodes))
  1689  	require.Equal(t, "db2", out.ServiceNodes[0].ServiceID)
  1690  
  1691  	// no tag, both instances
  1692  	args = structs.ServiceSpecificRequest{
  1693  		Datacenter:  "dc1",
  1694  		ServiceName: "db",
  1695  	}
  1696  	out = structs.IndexedServiceNodes{}
  1697  	err = msgpackrpc.CallWithCodec(codec, "Catalog.ServiceNodes", &args, &out)
  1698  	require.NoError(t, err)
  1699  	require.Equal(t, 2, len(out.ServiceNodes))
  1700  
  1701  	// DEPRECATED (singular-service-tag) - remove this when backwards RPC compat
  1702  	// with 1.2.x is not required.
  1703  	// when both ServiceTag and ServiceTags fields are populated, use ServiceTag
  1704  	args = structs.ServiceSpecificRequest{
  1705  		Datacenter:  "dc1",
  1706  		ServiceName: "db",
  1707  		ServiceTag:  "primary",
  1708  		ServiceTags: []string{"secondary"},
  1709  		TagFilter:   true,
  1710  	}
  1711  	out = structs.IndexedServiceNodes{}
  1712  	err = msgpackrpc.CallWithCodec(codec, "Catalog.ServiceNodes", &args, &out)
  1713  	require.NoError(t, err)
  1714  	require.Equal(t, "db1", out.ServiceNodes[0].ServiceID)
  1715  }
  1716  
  1717  func TestCatalog_ListServiceNodes_NodeMetaFilter(t *testing.T) {
  1718  	t.Parallel()
  1719  	dir1, s1 := testServer(t)
  1720  	defer os.RemoveAll(dir1)
  1721  	defer s1.Shutdown()
  1722  	codec := rpcClient(t, s1)
  1723  	defer codec.Close()
  1724  
  1725  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
  1726  
  1727  	// Add 2 nodes with specific meta maps
  1728  	node := &structs.Node{Node: "foo", Address: "127.0.0.1", Meta: map[string]string{"somekey": "somevalue", "common": "1"}}
  1729  	if err := s1.fsm.State().EnsureNode(1, node); err != nil {
  1730  		t.Fatalf("err: %v", err)
  1731  	}
  1732  	node2 := &structs.Node{Node: "bar", Address: "127.0.0.2", Meta: map[string]string{"common": "1"}}
  1733  	if err := s1.fsm.State().EnsureNode(2, node2); err != nil {
  1734  		t.Fatalf("err: %v", err)
  1735  	}
  1736  	if err := s1.fsm.State().EnsureService(3, "foo", &structs.NodeService{ID: "db", Service: "db", Tags: []string{"primary", "v2"}, Address: "127.0.0.1", Port: 5000}); err != nil {
  1737  		t.Fatalf("err: %v", err)
  1738  	}
  1739  	if err := s1.fsm.State().EnsureService(4, "bar", &structs.NodeService{ID: "db2", Service: "db", Tags: []string{"secondary", "v2"}, Address: "127.0.0.2", Port: 5000}); err != nil {
  1740  		t.Fatalf("err: %v", err)
  1741  	}
  1742  
  1743  	cases := []struct {
  1744  		filters  map[string]string
  1745  		tags     []string
  1746  		services structs.ServiceNodes
  1747  	}{
  1748  		// Basic meta filter
  1749  		{
  1750  			filters:  map[string]string{"somekey": "somevalue"},
  1751  			services: structs.ServiceNodes{&structs.ServiceNode{Node: "foo", ServiceID: "db"}},
  1752  		},
  1753  		// Basic meta filter, tag
  1754  		{
  1755  			filters:  map[string]string{"somekey": "somevalue"},
  1756  			tags:     []string{"primary"},
  1757  			services: structs.ServiceNodes{&structs.ServiceNode{Node: "foo", ServiceID: "db"}},
  1758  		},
  1759  		// Common meta filter
  1760  		{
  1761  			filters: map[string]string{"common": "1"},
  1762  			services: structs.ServiceNodes{
  1763  				&structs.ServiceNode{Node: "bar", ServiceID: "db2"},
  1764  				&structs.ServiceNode{Node: "foo", ServiceID: "db"},
  1765  			},
  1766  		},
  1767  		// Common meta filter, tag
  1768  		{
  1769  			filters: map[string]string{"common": "1"},
  1770  			tags:    []string{"secondary"},
  1771  			services: structs.ServiceNodes{
  1772  				&structs.ServiceNode{Node: "bar", ServiceID: "db2"},
  1773  			},
  1774  		},
  1775  		// Invalid meta filter
  1776  		{
  1777  			filters:  map[string]string{"invalid": "nope"},
  1778  			services: structs.ServiceNodes{},
  1779  		},
  1780  		// Multiple filter values
  1781  		{
  1782  			filters:  map[string]string{"somekey": "somevalue", "common": "1"},
  1783  			services: structs.ServiceNodes{&structs.ServiceNode{Node: "foo", ServiceID: "db"}},
  1784  		},
  1785  		// Multiple filter values, tag
  1786  		{
  1787  			filters:  map[string]string{"somekey": "somevalue", "common": "1"},
  1788  			tags:     []string{"primary"},
  1789  			services: structs.ServiceNodes{&structs.ServiceNode{Node: "foo", ServiceID: "db"}},
  1790  		},
  1791  		// Common meta filter, single tag
  1792  		{
  1793  			filters: map[string]string{"common": "1"},
  1794  			tags:    []string{"v2"},
  1795  			services: structs.ServiceNodes{
  1796  				&structs.ServiceNode{Node: "bar", ServiceID: "db2"},
  1797  				&structs.ServiceNode{Node: "foo", ServiceID: "db"},
  1798  			},
  1799  		},
  1800  		// Common meta filter, multiple tags
  1801  		{
  1802  			filters:  map[string]string{"common": "1"},
  1803  			tags:     []string{"v2", "primary"},
  1804  			services: structs.ServiceNodes{&structs.ServiceNode{Node: "foo", ServiceID: "db"}},
  1805  		},
  1806  	}
  1807  
  1808  	for _, tc := range cases {
  1809  		args := structs.ServiceSpecificRequest{
  1810  			Datacenter:      "dc1",
  1811  			NodeMetaFilters: tc.filters,
  1812  			ServiceName:     "db",
  1813  			ServiceTags:     tc.tags,
  1814  			TagFilter:       len(tc.tags) > 0,
  1815  		}
  1816  		var out structs.IndexedServiceNodes
  1817  		require.NoError(t, msgpackrpc.CallWithCodec(codec, "Catalog.ServiceNodes", &args, &out))
  1818  		require.Len(t, out.ServiceNodes, len(tc.services))
  1819  
  1820  		for i, serviceNode := range out.ServiceNodes {
  1821  			if serviceNode.Node != tc.services[i].Node || serviceNode.ServiceID != tc.services[i].ServiceID {
  1822  				t.Fatalf("bad: %v, %v filters: %v", serviceNode, tc.services[i], tc.filters)
  1823  			}
  1824  		}
  1825  	}
  1826  }
  1827  
  1828  func TestCatalog_ListServiceNodes_DistanceSort(t *testing.T) {
  1829  	t.Parallel()
  1830  	dir1, s1 := testServer(t)
  1831  	defer os.RemoveAll(dir1)
  1832  	defer s1.Shutdown()
  1833  	codec := rpcClient(t, s1)
  1834  	defer codec.Close()
  1835  
  1836  	args := structs.ServiceSpecificRequest{
  1837  		Datacenter:  "dc1",
  1838  		ServiceName: "db",
  1839  	}
  1840  	var out structs.IndexedServiceNodes
  1841  	err := msgpackrpc.CallWithCodec(codec, "Catalog.ServiceNodes", &args, &out)
  1842  	if err != nil {
  1843  		t.Fatalf("err: %v", err)
  1844  	}
  1845  
  1846  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
  1847  
  1848  	// Add a few nodes for the associated services.
  1849  	s1.fsm.State().EnsureNode(1, &structs.Node{Node: "aaa", Address: "127.0.0.1"})
  1850  	s1.fsm.State().EnsureService(2, "aaa", &structs.NodeService{ID: "db", Service: "db", Tags: []string{"primary"}, Address: "127.0.0.1", Port: 5000})
  1851  	s1.fsm.State().EnsureNode(3, &structs.Node{Node: "foo", Address: "127.0.0.2"})
  1852  	s1.fsm.State().EnsureService(4, "foo", &structs.NodeService{ID: "db", Service: "db", Tags: []string{"primary"}, Address: "127.0.0.2", Port: 5000})
  1853  	s1.fsm.State().EnsureNode(5, &structs.Node{Node: "bar", Address: "127.0.0.3"})
  1854  	s1.fsm.State().EnsureService(6, "bar", &structs.NodeService{ID: "db", Service: "db", Tags: []string{"primary"}, Address: "127.0.0.3", Port: 5000})
  1855  	s1.fsm.State().EnsureNode(7, &structs.Node{Node: "baz", Address: "127.0.0.4"})
  1856  	s1.fsm.State().EnsureService(8, "baz", &structs.NodeService{ID: "db", Service: "db", Tags: []string{"primary"}, Address: "127.0.0.4", Port: 5000})
  1857  
  1858  	// Set all but one of the nodes to known coordinates.
  1859  	updates := structs.Coordinates{
  1860  		{Node: "foo", Coord: lib.GenerateCoordinate(2 * time.Millisecond)},
  1861  		{Node: "bar", Coord: lib.GenerateCoordinate(5 * time.Millisecond)},
  1862  		{Node: "baz", Coord: lib.GenerateCoordinate(1 * time.Millisecond)},
  1863  	}
  1864  	if err := s1.fsm.State().CoordinateBatchUpdate(9, updates); err != nil {
  1865  		t.Fatalf("err: %v", err)
  1866  	}
  1867  
  1868  	// Query with no given source node, should get the natural order from
  1869  	// the index.
  1870  	if err := msgpackrpc.CallWithCodec(codec, "Catalog.ServiceNodes", &args, &out); err != nil {
  1871  		t.Fatalf("err: %v", err)
  1872  	}
  1873  	if len(out.ServiceNodes) != 4 {
  1874  		t.Fatalf("bad: %v", out)
  1875  	}
  1876  	if out.ServiceNodes[0].Node != "aaa" {
  1877  		t.Fatalf("bad: %v", out)
  1878  	}
  1879  	if out.ServiceNodes[1].Node != "bar" {
  1880  		t.Fatalf("bad: %v", out)
  1881  	}
  1882  	if out.ServiceNodes[2].Node != "baz" {
  1883  		t.Fatalf("bad: %v", out)
  1884  	}
  1885  	if out.ServiceNodes[3].Node != "foo" {
  1886  		t.Fatalf("bad: %v", out)
  1887  	}
  1888  
  1889  	// Query relative to foo, note that there's no known coordinate for "aaa"
  1890  	// so it will go at the end.
  1891  	args = structs.ServiceSpecificRequest{
  1892  		Datacenter:  "dc1",
  1893  		ServiceName: "db",
  1894  		Source:      structs.QuerySource{Datacenter: "dc1", Node: "foo"},
  1895  	}
  1896  	if err := msgpackrpc.CallWithCodec(codec, "Catalog.ServiceNodes", &args, &out); err != nil {
  1897  		t.Fatalf("err: %v", err)
  1898  	}
  1899  	if len(out.ServiceNodes) != 4 {
  1900  		t.Fatalf("bad: %v", out)
  1901  	}
  1902  	if out.ServiceNodes[0].Node != "foo" {
  1903  		t.Fatalf("bad: %v", out)
  1904  	}
  1905  	if out.ServiceNodes[1].Node != "baz" {
  1906  		t.Fatalf("bad: %v", out)
  1907  	}
  1908  	if out.ServiceNodes[2].Node != "bar" {
  1909  		t.Fatalf("bad: %v", out)
  1910  	}
  1911  	if out.ServiceNodes[3].Node != "aaa" {
  1912  		t.Fatalf("bad: %v", out)
  1913  	}
  1914  }
  1915  
  1916  func TestCatalog_ListServiceNodes_ConnectProxy(t *testing.T) {
  1917  	t.Parallel()
  1918  
  1919  	assert := assert.New(t)
  1920  	dir1, s1 := testServer(t)
  1921  	defer os.RemoveAll(dir1)
  1922  	defer s1.Shutdown()
  1923  	codec := rpcClient(t, s1)
  1924  	defer codec.Close()
  1925  
  1926  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
  1927  
  1928  	// Register the service
  1929  	args := structs.TestRegisterRequestProxy(t)
  1930  	var out struct{}
  1931  	assert.Nil(msgpackrpc.CallWithCodec(codec, "Catalog.Register", args, &out))
  1932  
  1933  	// List
  1934  	req := structs.ServiceSpecificRequest{
  1935  		Datacenter:  "dc1",
  1936  		ServiceName: args.Service.Service,
  1937  		TagFilter:   false,
  1938  	}
  1939  	var resp structs.IndexedServiceNodes
  1940  	assert.Nil(msgpackrpc.CallWithCodec(codec, "Catalog.ServiceNodes", &req, &resp))
  1941  	assert.Len(resp.ServiceNodes, 1)
  1942  	v := resp.ServiceNodes[0]
  1943  	assert.Equal(structs.ServiceKindConnectProxy, v.ServiceKind)
  1944  	assert.Equal(args.Service.Proxy.DestinationServiceName, v.ServiceProxy.DestinationServiceName)
  1945  }
  1946  
  1947  func TestCatalog_ListServiceNodes_ConnectDestination(t *testing.T) {
  1948  	t.Parallel()
  1949  
  1950  	assert := assert.New(t)
  1951  	dir1, s1 := testServer(t)
  1952  	defer os.RemoveAll(dir1)
  1953  	defer s1.Shutdown()
  1954  	codec := rpcClient(t, s1)
  1955  	defer codec.Close()
  1956  
  1957  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
  1958  
  1959  	// Register the proxy service
  1960  	args := structs.TestRegisterRequestProxy(t)
  1961  	var out struct{}
  1962  	assert.Nil(msgpackrpc.CallWithCodec(codec, "Catalog.Register", args, &out))
  1963  
  1964  	// Register the service
  1965  	{
  1966  		dst := args.Service.Proxy.DestinationServiceName
  1967  		args := structs.TestRegisterRequest(t)
  1968  		args.Service.Service = dst
  1969  		var out struct{}
  1970  		assert.Nil(msgpackrpc.CallWithCodec(codec, "Catalog.Register", args, &out))
  1971  	}
  1972  
  1973  	// List
  1974  	req := structs.ServiceSpecificRequest{
  1975  		Connect:     true,
  1976  		Datacenter:  "dc1",
  1977  		ServiceName: args.Service.Proxy.DestinationServiceName,
  1978  	}
  1979  	var resp structs.IndexedServiceNodes
  1980  	assert.Nil(msgpackrpc.CallWithCodec(codec, "Catalog.ServiceNodes", &req, &resp))
  1981  	assert.Len(resp.ServiceNodes, 1)
  1982  	v := resp.ServiceNodes[0]
  1983  	assert.Equal(structs.ServiceKindConnectProxy, v.ServiceKind)
  1984  	assert.Equal(args.Service.Proxy.DestinationServiceName, v.ServiceProxy.DestinationServiceName)
  1985  
  1986  	// List by non-Connect
  1987  	req = structs.ServiceSpecificRequest{
  1988  		Datacenter:  "dc1",
  1989  		ServiceName: args.Service.Proxy.DestinationServiceName,
  1990  	}
  1991  	assert.Nil(msgpackrpc.CallWithCodec(codec, "Catalog.ServiceNodes", &req, &resp))
  1992  	assert.Len(resp.ServiceNodes, 1)
  1993  	v = resp.ServiceNodes[0]
  1994  	assert.Equal(args.Service.Proxy.DestinationServiceName, v.ServiceName)
  1995  	assert.Equal("", v.ServiceProxy.DestinationServiceName)
  1996  }
  1997  
  1998  // Test that calling ServiceNodes with Connect: true will return
  1999  // Connect native services.
  2000  func TestCatalog_ListServiceNodes_ConnectDestinationNative(t *testing.T) {
  2001  	t.Parallel()
  2002  
  2003  	require := require.New(t)
  2004  	dir1, s1 := testServer(t)
  2005  	defer os.RemoveAll(dir1)
  2006  	defer s1.Shutdown()
  2007  	codec := rpcClient(t, s1)
  2008  	defer codec.Close()
  2009  
  2010  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
  2011  
  2012  	// Register the native service
  2013  	args := structs.TestRegisterRequest(t)
  2014  	args.Service.Connect.Native = true
  2015  	var out struct{}
  2016  	require.Nil(msgpackrpc.CallWithCodec(codec, "Catalog.Register", args, &out))
  2017  
  2018  	// List
  2019  	req := structs.ServiceSpecificRequest{
  2020  		Connect:     true,
  2021  		Datacenter:  "dc1",
  2022  		ServiceName: args.Service.Service,
  2023  	}
  2024  	var resp structs.IndexedServiceNodes
  2025  	require.Nil(msgpackrpc.CallWithCodec(codec, "Catalog.ServiceNodes", &req, &resp))
  2026  	require.Len(resp.ServiceNodes, 1)
  2027  	v := resp.ServiceNodes[0]
  2028  	require.Equal(args.Service.Service, v.ServiceName)
  2029  
  2030  	// List by non-Connect
  2031  	req = structs.ServiceSpecificRequest{
  2032  		Datacenter:  "dc1",
  2033  		ServiceName: args.Service.Service,
  2034  	}
  2035  	require.Nil(msgpackrpc.CallWithCodec(codec, "Catalog.ServiceNodes", &req, &resp))
  2036  	require.Len(resp.ServiceNodes, 1)
  2037  	v = resp.ServiceNodes[0]
  2038  	require.Equal(args.Service.Service, v.ServiceName)
  2039  }
  2040  
  2041  func TestCatalog_ListServiceNodes_ConnectProxy_ACL(t *testing.T) {
  2042  	t.Parallel()
  2043  
  2044  	assert := assert.New(t)
  2045  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
  2046  		c.ACLDatacenter = "dc1"
  2047  		c.ACLsEnabled = true
  2048  		c.ACLMasterToken = "root"
  2049  		c.ACLDefaultPolicy = "deny"
  2050  	})
  2051  	defer os.RemoveAll(dir1)
  2052  	defer s1.Shutdown()
  2053  	codec := rpcClient(t, s1)
  2054  	defer codec.Close()
  2055  
  2056  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
  2057  
  2058  	// Create the ACL.
  2059  	arg := structs.ACLRequest{
  2060  		Datacenter: "dc1",
  2061  		Op:         structs.ACLSet,
  2062  		ACL: structs.ACL{
  2063  			Name: "User token",
  2064  			Type: structs.ACLTokenTypeClient,
  2065  			Rules: `
  2066  service "foo" {
  2067  	policy = "write"
  2068  }
  2069  `,
  2070  		},
  2071  		WriteRequest: structs.WriteRequest{Token: "root"},
  2072  	}
  2073  	var token string
  2074  	assert.Nil(msgpackrpc.CallWithCodec(codec, "ACL.Apply", &arg, &token))
  2075  
  2076  	{
  2077  		// Register a proxy
  2078  		args := structs.TestRegisterRequestProxy(t)
  2079  		args.Service.Service = "foo-proxy"
  2080  		args.Service.Proxy.DestinationServiceName = "bar"
  2081  		args.WriteRequest.Token = "root"
  2082  		var out struct{}
  2083  		assert.Nil(msgpackrpc.CallWithCodec(codec, "Catalog.Register", &args, &out))
  2084  
  2085  		// Register a proxy
  2086  		args = structs.TestRegisterRequestProxy(t)
  2087  		args.Service.Service = "foo-proxy"
  2088  		args.Service.Proxy.DestinationServiceName = "foo"
  2089  		args.WriteRequest.Token = "root"
  2090  		assert.Nil(msgpackrpc.CallWithCodec(codec, "Catalog.Register", &args, &out))
  2091  
  2092  		// Register a proxy
  2093  		args = structs.TestRegisterRequestProxy(t)
  2094  		args.Service.Service = "another-proxy"
  2095  		args.Service.Proxy.DestinationServiceName = "foo"
  2096  		args.WriteRequest.Token = "root"
  2097  		assert.Nil(msgpackrpc.CallWithCodec(codec, "Catalog.Register", &args, &out))
  2098  	}
  2099  
  2100  	// List w/ token. This should disallow because we don't have permission
  2101  	// to read "bar"
  2102  	req := structs.ServiceSpecificRequest{
  2103  		Connect:      true,
  2104  		Datacenter:   "dc1",
  2105  		ServiceName:  "bar",
  2106  		QueryOptions: structs.QueryOptions{Token: token},
  2107  	}
  2108  	var resp structs.IndexedServiceNodes
  2109  	assert.Nil(msgpackrpc.CallWithCodec(codec, "Catalog.ServiceNodes", &req, &resp))
  2110  	assert.Len(resp.ServiceNodes, 0)
  2111  
  2112  	// List w/ token. This should work since we're requesting "foo", but should
  2113  	// also only contain the proxies with names that adhere to our ACL.
  2114  	req = structs.ServiceSpecificRequest{
  2115  		Connect:      true,
  2116  		Datacenter:   "dc1",
  2117  		ServiceName:  "foo",
  2118  		QueryOptions: structs.QueryOptions{Token: token},
  2119  	}
  2120  	assert.Nil(msgpackrpc.CallWithCodec(codec, "Catalog.ServiceNodes", &req, &resp))
  2121  	assert.Len(resp.ServiceNodes, 1)
  2122  	v := resp.ServiceNodes[0]
  2123  	assert.Equal("foo-proxy", v.ServiceName)
  2124  }
  2125  
  2126  func TestCatalog_ListServiceNodes_ConnectNative(t *testing.T) {
  2127  	t.Parallel()
  2128  
  2129  	assert := assert.New(t)
  2130  	dir1, s1 := testServer(t)
  2131  	defer os.RemoveAll(dir1)
  2132  	defer s1.Shutdown()
  2133  	codec := rpcClient(t, s1)
  2134  	defer codec.Close()
  2135  
  2136  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
  2137  
  2138  	// Register the service
  2139  	args := structs.TestRegisterRequest(t)
  2140  	args.Service.Connect.Native = true
  2141  	var out struct{}
  2142  	assert.Nil(msgpackrpc.CallWithCodec(codec, "Catalog.Register", args, &out))
  2143  
  2144  	// List
  2145  	req := structs.ServiceSpecificRequest{
  2146  		Datacenter:  "dc1",
  2147  		ServiceName: args.Service.Service,
  2148  		TagFilter:   false,
  2149  	}
  2150  	var resp structs.IndexedServiceNodes
  2151  	assert.Nil(msgpackrpc.CallWithCodec(codec, "Catalog.ServiceNodes", &req, &resp))
  2152  	assert.Len(resp.ServiceNodes, 1)
  2153  	v := resp.ServiceNodes[0]
  2154  	assert.Equal(args.Service.Connect.Native, v.ServiceConnect.Native)
  2155  }
  2156  
  2157  func TestCatalog_NodeServices(t *testing.T) {
  2158  	t.Parallel()
  2159  	dir1, s1 := testServer(t)
  2160  	defer os.RemoveAll(dir1)
  2161  	defer s1.Shutdown()
  2162  	codec := rpcClient(t, s1)
  2163  	defer codec.Close()
  2164  	testrpc.WaitForTestAgent(t, s1.RPC, "dc1")
  2165  
  2166  	args := structs.NodeSpecificRequest{
  2167  		Datacenter: "dc1",
  2168  		Node:       "foo",
  2169  	}
  2170  	var out structs.IndexedNodeServices
  2171  	err := msgpackrpc.CallWithCodec(codec, "Catalog.NodeServices", &args, &out)
  2172  	if err != nil {
  2173  		t.Fatalf("err: %v", err)
  2174  	}
  2175  
  2176  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
  2177  
  2178  	// Just add a node
  2179  	if err := s1.fsm.State().EnsureNode(1, &structs.Node{Node: "foo", Address: "127.0.0.1"}); err != nil {
  2180  		t.Fatalf("err: %v", err)
  2181  	}
  2182  	if err := s1.fsm.State().EnsureService(2, "foo", &structs.NodeService{ID: "db", Service: "db", Tags: []string{"primary"}, Address: "127.0.0.1", Port: 5000}); err != nil {
  2183  		t.Fatalf("err: %v", err)
  2184  	}
  2185  	if err := s1.fsm.State().EnsureService(3, "foo", &structs.NodeService{ID: "web", Service: "web", Tags: nil, Address: "127.0.0.1", Port: 80}); err != nil {
  2186  		t.Fatalf("err: %v", err)
  2187  	}
  2188  
  2189  	if err := msgpackrpc.CallWithCodec(codec, "Catalog.NodeServices", &args, &out); err != nil {
  2190  		t.Fatalf("err: %v", err)
  2191  	}
  2192  
  2193  	if out.NodeServices.Node.Address != "127.0.0.1" {
  2194  		t.Fatalf("bad: %v", out)
  2195  	}
  2196  	if len(out.NodeServices.Services) != 2 {
  2197  		t.Fatalf("bad: %v", out)
  2198  	}
  2199  	services := out.NodeServices.Services
  2200  	if !lib.StrContains(services["db"].Tags, "primary") || services["db"].Port != 5000 {
  2201  		t.Fatalf("bad: %v", out)
  2202  	}
  2203  	if len(services["web"].Tags) != 0 || services["web"].Port != 80 {
  2204  		t.Fatalf("bad: %v", out)
  2205  	}
  2206  }
  2207  
  2208  func TestCatalog_NodeServices_ConnectProxy(t *testing.T) {
  2209  	t.Parallel()
  2210  
  2211  	assert := assert.New(t)
  2212  	dir1, s1 := testServer(t)
  2213  	defer os.RemoveAll(dir1)
  2214  	defer s1.Shutdown()
  2215  	codec := rpcClient(t, s1)
  2216  	defer codec.Close()
  2217  
  2218  	testrpc.WaitForTestAgent(t, s1.RPC, "dc1")
  2219  
  2220  	// Register the service
  2221  	args := structs.TestRegisterRequestProxy(t)
  2222  	var out struct{}
  2223  	assert.Nil(msgpackrpc.CallWithCodec(codec, "Catalog.Register", args, &out))
  2224  
  2225  	// List
  2226  	req := structs.NodeSpecificRequest{
  2227  		Datacenter: "dc1",
  2228  		Node:       args.Node,
  2229  	}
  2230  	var resp structs.IndexedNodeServices
  2231  	assert.Nil(msgpackrpc.CallWithCodec(codec, "Catalog.NodeServices", &req, &resp))
  2232  
  2233  	assert.Len(resp.NodeServices.Services, 1)
  2234  	v := resp.NodeServices.Services[args.Service.Service]
  2235  	assert.Equal(structs.ServiceKindConnectProxy, v.Kind)
  2236  	assert.Equal(args.Service.Proxy.DestinationServiceName, v.Proxy.DestinationServiceName)
  2237  }
  2238  
  2239  func TestCatalog_NodeServices_ConnectNative(t *testing.T) {
  2240  	t.Parallel()
  2241  
  2242  	assert := assert.New(t)
  2243  	dir1, s1 := testServer(t)
  2244  	defer os.RemoveAll(dir1)
  2245  	defer s1.Shutdown()
  2246  	codec := rpcClient(t, s1)
  2247  	defer codec.Close()
  2248  
  2249  	testrpc.WaitForTestAgent(t, s1.RPC, "dc1")
  2250  
  2251  	// Register the service
  2252  	args := structs.TestRegisterRequest(t)
  2253  	var out struct{}
  2254  	assert.Nil(msgpackrpc.CallWithCodec(codec, "Catalog.Register", args, &out))
  2255  
  2256  	// List
  2257  	req := structs.NodeSpecificRequest{
  2258  		Datacenter: "dc1",
  2259  		Node:       args.Node,
  2260  	}
  2261  	var resp structs.IndexedNodeServices
  2262  	assert.Nil(msgpackrpc.CallWithCodec(codec, "Catalog.NodeServices", &req, &resp))
  2263  
  2264  	assert.Len(resp.NodeServices.Services, 1)
  2265  	v := resp.NodeServices.Services[args.Service.Service]
  2266  	assert.Equal(args.Service.Connect.Native, v.Connect.Native)
  2267  }
  2268  
  2269  // Used to check for a regression against a known bug
  2270  func TestCatalog_Register_FailedCase1(t *testing.T) {
  2271  	t.Parallel()
  2272  	dir1, s1 := testServer(t)
  2273  	defer os.RemoveAll(dir1)
  2274  	defer s1.Shutdown()
  2275  	codec := rpcClient(t, s1)
  2276  	defer codec.Close()
  2277  
  2278  	arg := structs.RegisterRequest{
  2279  		Datacenter: "dc1",
  2280  		Node:       "bar",
  2281  		Address:    "127.0.0.2",
  2282  		Service: &structs.NodeService{
  2283  			Service: "web",
  2284  			Tags:    nil,
  2285  			Port:    8000,
  2286  		},
  2287  	}
  2288  	var out struct{}
  2289  
  2290  	err := msgpackrpc.CallWithCodec(codec, "Catalog.Register", &arg, &out)
  2291  	if err != nil {
  2292  		t.Fatalf("err: %v", err)
  2293  	}
  2294  
  2295  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
  2296  
  2297  	if err := msgpackrpc.CallWithCodec(codec, "Catalog.Register", &arg, &out); err != nil {
  2298  		t.Fatalf("err: %v", err)
  2299  	}
  2300  
  2301  	// Check we can get this back
  2302  	query := &structs.ServiceSpecificRequest{
  2303  		Datacenter:  "dc1",
  2304  		ServiceName: "web",
  2305  	}
  2306  	var out2 structs.IndexedServiceNodes
  2307  	if err := msgpackrpc.CallWithCodec(codec, "Catalog.ServiceNodes", query, &out2); err != nil {
  2308  		t.Fatalf("err: %v", err)
  2309  	}
  2310  
  2311  	// Check the output
  2312  	if len(out2.ServiceNodes) != 1 {
  2313  		t.Fatalf("Bad: %v", out2)
  2314  	}
  2315  }
  2316  
  2317  func testACLFilterServer(t *testing.T) (dir, token string, srv *Server, codec rpc.ClientCodec) {
  2318  	dir, srv = testServerWithConfig(t, func(c *Config) {
  2319  		c.ACLDatacenter = "dc1"
  2320  		c.ACLsEnabled = true
  2321  		c.ACLMasterToken = "root"
  2322  		c.ACLDefaultPolicy = "deny"
  2323  		c.ACLEnforceVersion8 = false
  2324  	})
  2325  
  2326  	codec = rpcClient(t, srv)
  2327  	testrpc.WaitForLeader(t, srv.RPC, "dc1")
  2328  
  2329  	// Create a new token
  2330  	arg := structs.ACLRequest{
  2331  		Datacenter: "dc1",
  2332  		Op:         structs.ACLSet,
  2333  		ACL: structs.ACL{
  2334  			Name: "User token",
  2335  			Type: structs.ACLTokenTypeClient,
  2336  			Rules: `
  2337  service "foo" {
  2338  	policy = "write"
  2339  }
  2340  `,
  2341  		},
  2342  		WriteRequest: structs.WriteRequest{Token: "root"},
  2343  	}
  2344  	if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &arg, &token); err != nil {
  2345  		t.Fatalf("err: %v", err)
  2346  	}
  2347  
  2348  	// Register a service
  2349  	regArg := structs.RegisterRequest{
  2350  		Datacenter: "dc1",
  2351  		Node:       srv.config.NodeName,
  2352  		Address:    "127.0.0.1",
  2353  		Service: &structs.NodeService{
  2354  			ID:      "foo",
  2355  			Service: "foo",
  2356  		},
  2357  		Check: &structs.HealthCheck{
  2358  			CheckID:   "service:foo",
  2359  			Name:      "service:foo",
  2360  			ServiceID: "foo",
  2361  			Status:    api.HealthPassing,
  2362  		},
  2363  		WriteRequest: structs.WriteRequest{Token: "root"},
  2364  	}
  2365  	if err := msgpackrpc.CallWithCodec(codec, "Catalog.Register", &regArg, nil); err != nil {
  2366  		t.Fatalf("err: %s", err)
  2367  	}
  2368  
  2369  	// Register a service which should be denied
  2370  	regArg = structs.RegisterRequest{
  2371  		Datacenter: "dc1",
  2372  		Node:       srv.config.NodeName,
  2373  		Address:    "127.0.0.1",
  2374  		Service: &structs.NodeService{
  2375  			ID:      "bar",
  2376  			Service: "bar",
  2377  		},
  2378  		Check: &structs.HealthCheck{
  2379  			CheckID:   "service:bar",
  2380  			Name:      "service:bar",
  2381  			ServiceID: "bar",
  2382  		},
  2383  		WriteRequest: structs.WriteRequest{Token: "root"},
  2384  	}
  2385  	if err := msgpackrpc.CallWithCodec(codec, "Catalog.Register", &regArg, nil); err != nil {
  2386  		t.Fatalf("err: %s", err)
  2387  	}
  2388  	return
  2389  }
  2390  
  2391  func TestCatalog_ListServices_FilterACL(t *testing.T) {
  2392  	t.Parallel()
  2393  	dir, token, srv, codec := testACLFilterServer(t)
  2394  	defer os.RemoveAll(dir)
  2395  	defer srv.Shutdown()
  2396  	defer codec.Close()
  2397  	testrpc.WaitForTestAgent(t, srv.RPC, "dc1")
  2398  
  2399  	opt := structs.DCSpecificRequest{
  2400  		Datacenter:   "dc1",
  2401  		QueryOptions: structs.QueryOptions{Token: token},
  2402  	}
  2403  	reply := structs.IndexedServices{}
  2404  	if err := msgpackrpc.CallWithCodec(codec, "Catalog.ListServices", &opt, &reply); err != nil {
  2405  		t.Fatalf("err: %s", err)
  2406  	}
  2407  	if _, ok := reply.Services["foo"]; !ok {
  2408  		t.Fatalf("bad: %#v", reply.Services)
  2409  	}
  2410  	if _, ok := reply.Services["bar"]; ok {
  2411  		t.Fatalf("bad: %#v", reply.Services)
  2412  	}
  2413  }
  2414  
  2415  func TestCatalog_ServiceNodes_FilterACL(t *testing.T) {
  2416  	t.Parallel()
  2417  	dir, token, srv, codec := testACLFilterServer(t)
  2418  	defer os.RemoveAll(dir)
  2419  	defer srv.Shutdown()
  2420  	defer codec.Close()
  2421  
  2422  	opt := structs.ServiceSpecificRequest{
  2423  		Datacenter:   "dc1",
  2424  		ServiceName:  "foo",
  2425  		QueryOptions: structs.QueryOptions{Token: token},
  2426  	}
  2427  	reply := structs.IndexedServiceNodes{}
  2428  	if err := msgpackrpc.CallWithCodec(codec, "Catalog.ServiceNodes", &opt, &reply); err != nil {
  2429  		t.Fatalf("err: %s", err)
  2430  	}
  2431  	found := false
  2432  	for _, sn := range reply.ServiceNodes {
  2433  		if sn.ServiceID == "foo" {
  2434  			found = true
  2435  			break
  2436  		}
  2437  	}
  2438  	if !found {
  2439  		t.Fatalf("bad: %#v", reply.ServiceNodes)
  2440  	}
  2441  
  2442  	// Filters services we can't access
  2443  	opt = structs.ServiceSpecificRequest{
  2444  		Datacenter:   "dc1",
  2445  		ServiceName:  "bar",
  2446  		QueryOptions: structs.QueryOptions{Token: token},
  2447  	}
  2448  	reply = structs.IndexedServiceNodes{}
  2449  	if err := msgpackrpc.CallWithCodec(codec, "Catalog.ServiceNodes", &opt, &reply); err != nil {
  2450  		t.Fatalf("err: %s", err)
  2451  	}
  2452  	for _, sn := range reply.ServiceNodes {
  2453  		if sn.ServiceID == "bar" {
  2454  			t.Fatalf("bad: %#v", reply.ServiceNodes)
  2455  		}
  2456  	}
  2457  
  2458  	// We've already proven that we call the ACL filtering function so we
  2459  	// test node filtering down in acl.go for node cases. This also proves
  2460  	// that we respect the version 8 ACL flag, since the test server sets
  2461  	// that to false (the regression value of *not* changing this is better
  2462  	// for now until we change the sense of the version 8 ACL flag).
  2463  }
  2464  
  2465  func TestCatalog_NodeServices_ACLDeny(t *testing.T) {
  2466  	t.Parallel()
  2467  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
  2468  		c.ACLDatacenter = "dc1"
  2469  		c.ACLsEnabled = true
  2470  		c.ACLMasterToken = "root"
  2471  		c.ACLDefaultPolicy = "deny"
  2472  		c.ACLEnforceVersion8 = false
  2473  	})
  2474  	defer os.RemoveAll(dir1)
  2475  	defer s1.Shutdown()
  2476  	codec := rpcClient(t, s1)
  2477  	defer codec.Close()
  2478  
  2479  	testrpc.WaitForTestAgent(t, s1.RPC, "dc1")
  2480  
  2481  	// Prior to version 8, the node policy should be ignored.
  2482  	args := structs.NodeSpecificRequest{
  2483  		Datacenter: "dc1",
  2484  		Node:       s1.config.NodeName,
  2485  	}
  2486  	reply := structs.IndexedNodeServices{}
  2487  	if err := msgpackrpc.CallWithCodec(codec, "Catalog.NodeServices", &args, &reply); err != nil {
  2488  		t.Fatalf("err: %v", err)
  2489  	}
  2490  	if reply.NodeServices == nil {
  2491  		t.Fatalf("should not be nil")
  2492  	}
  2493  
  2494  	// Now turn on version 8 enforcement and try again.
  2495  	s1.config.ACLEnforceVersion8 = true
  2496  	if err := msgpackrpc.CallWithCodec(codec, "Catalog.NodeServices", &args, &reply); err != nil {
  2497  		t.Fatalf("err: %v", err)
  2498  	}
  2499  	if reply.NodeServices != nil {
  2500  		t.Fatalf("should not nil")
  2501  	}
  2502  
  2503  	// Create an ACL that can read the node.
  2504  	arg := structs.ACLRequest{
  2505  		Datacenter: "dc1",
  2506  		Op:         structs.ACLSet,
  2507  		ACL: structs.ACL{
  2508  			Name: "User token",
  2509  			Type: structs.ACLTokenTypeClient,
  2510  			Rules: fmt.Sprintf(`
  2511  node "%s" {
  2512  	policy = "read"
  2513  }
  2514  `, s1.config.NodeName),
  2515  		},
  2516  		WriteRequest: structs.WriteRequest{Token: "root"},
  2517  	}
  2518  	var id string
  2519  	if err := msgpackrpc.CallWithCodec(codec, "ACL.Apply", &arg, &id); err != nil {
  2520  		t.Fatalf("err: %v", err)
  2521  	}
  2522  
  2523  	// Now try with the token and it will go through.
  2524  	args.Token = id
  2525  	if err := msgpackrpc.CallWithCodec(codec, "Catalog.NodeServices", &args, &reply); err != nil {
  2526  		t.Fatalf("err: %v", err)
  2527  	}
  2528  	if reply.NodeServices == nil {
  2529  		t.Fatalf("should not be nil")
  2530  	}
  2531  
  2532  	// Make sure an unknown node doesn't cause trouble.
  2533  	args.Node = "nope"
  2534  	if err := msgpackrpc.CallWithCodec(codec, "Catalog.NodeServices", &args, &reply); err != nil {
  2535  		t.Fatalf("err: %v", err)
  2536  	}
  2537  	if reply.NodeServices != nil {
  2538  		t.Fatalf("should not nil")
  2539  	}
  2540  }
  2541  
  2542  func TestCatalog_NodeServices_FilterACL(t *testing.T) {
  2543  	t.Parallel()
  2544  	dir, token, srv, codec := testACLFilterServer(t)
  2545  	defer os.RemoveAll(dir)
  2546  	defer srv.Shutdown()
  2547  	defer codec.Close()
  2548  	testrpc.WaitForTestAgent(t, srv.RPC, "dc1")
  2549  
  2550  	opt := structs.NodeSpecificRequest{
  2551  		Datacenter:   "dc1",
  2552  		Node:         srv.config.NodeName,
  2553  		QueryOptions: structs.QueryOptions{Token: token},
  2554  	}
  2555  	reply := structs.IndexedNodeServices{}
  2556  	if err := msgpackrpc.CallWithCodec(codec, "Catalog.NodeServices", &opt, &reply); err != nil {
  2557  		t.Fatalf("err: %s", err)
  2558  	}
  2559  	found := false
  2560  	for _, svc := range reply.NodeServices.Services {
  2561  		if svc.ID == "bar" {
  2562  			t.Fatalf("bad: %#v", reply.NodeServices.Services)
  2563  		}
  2564  		if svc.ID == "foo" {
  2565  			found = true
  2566  			break
  2567  		}
  2568  	}
  2569  	if !found {
  2570  		t.Fatalf("bad: %#v", reply.NodeServices)
  2571  	}
  2572  }