github.phpd.cn/hashicorp/consul@v1.4.5/agent/consul/intention_endpoint_test.go (about)

     1  package consul
     2  
     3  import (
     4  	"os"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/hashicorp/consul/acl"
     9  	"github.com/hashicorp/consul/agent/structs"
    10  	"github.com/hashicorp/consul/testrpc"
    11  	"github.com/hashicorp/net-rpc-msgpackrpc"
    12  	"github.com/stretchr/testify/assert"
    13  	"github.com/stretchr/testify/require"
    14  )
    15  
    16  // Test basic creation
    17  func TestIntentionApply_new(t *testing.T) {
    18  	t.Parallel()
    19  
    20  	assert := assert.New(t)
    21  	dir1, s1 := testServer(t)
    22  	defer os.RemoveAll(dir1)
    23  	defer s1.Shutdown()
    24  	codec := rpcClient(t, s1)
    25  	defer codec.Close()
    26  
    27  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
    28  
    29  	// Setup a basic record to create
    30  	ixn := structs.IntentionRequest{
    31  		Datacenter: "dc1",
    32  		Op:         structs.IntentionOpCreate,
    33  		Intention: &structs.Intention{
    34  			SourceNS:        structs.IntentionDefaultNamespace,
    35  			SourceName:      "test",
    36  			DestinationNS:   structs.IntentionDefaultNamespace,
    37  			DestinationName: "test",
    38  			Action:          structs.IntentionActionAllow,
    39  			SourceType:      structs.IntentionSourceConsul,
    40  			Meta:            map[string]string{},
    41  		},
    42  	}
    43  	var reply string
    44  
    45  	// Record now to check created at time
    46  	now := time.Now()
    47  
    48  	// Create
    49  	assert.Nil(msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply))
    50  	assert.NotEmpty(reply)
    51  
    52  	// Read
    53  	ixn.Intention.ID = reply
    54  	{
    55  		req := &structs.IntentionQueryRequest{
    56  			Datacenter:  "dc1",
    57  			IntentionID: ixn.Intention.ID,
    58  		}
    59  		var resp structs.IndexedIntentions
    60  		assert.Nil(msgpackrpc.CallWithCodec(codec, "Intention.Get", req, &resp))
    61  		assert.Len(resp.Intentions, 1)
    62  		actual := resp.Intentions[0]
    63  		assert.Equal(resp.Index, actual.ModifyIndex)
    64  		assert.WithinDuration(now, actual.CreatedAt, 5*time.Second)
    65  		assert.WithinDuration(now, actual.UpdatedAt, 5*time.Second)
    66  
    67  		actual.CreateIndex, actual.ModifyIndex = 0, 0
    68  		actual.CreatedAt = ixn.Intention.CreatedAt
    69  		actual.UpdatedAt = ixn.Intention.UpdatedAt
    70  		ixn.Intention.UpdatePrecedence()
    71  		assert.Equal(ixn.Intention, actual)
    72  	}
    73  }
    74  
    75  // Test the source type defaults
    76  func TestIntentionApply_defaultSourceType(t *testing.T) {
    77  	t.Parallel()
    78  
    79  	assert := assert.New(t)
    80  	dir1, s1 := testServer(t)
    81  	defer os.RemoveAll(dir1)
    82  	defer s1.Shutdown()
    83  	codec := rpcClient(t, s1)
    84  	defer codec.Close()
    85  
    86  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
    87  
    88  	// Setup a basic record to create
    89  	ixn := structs.IntentionRequest{
    90  		Datacenter: "dc1",
    91  		Op:         structs.IntentionOpCreate,
    92  		Intention: &structs.Intention{
    93  			SourceNS:        structs.IntentionDefaultNamespace,
    94  			SourceName:      "test",
    95  			DestinationNS:   structs.IntentionDefaultNamespace,
    96  			DestinationName: "test",
    97  			Action:          structs.IntentionActionAllow,
    98  		},
    99  	}
   100  	var reply string
   101  
   102  	// Create
   103  	assert.Nil(msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply))
   104  	assert.NotEmpty(reply)
   105  
   106  	// Read
   107  	ixn.Intention.ID = reply
   108  	{
   109  		req := &structs.IntentionQueryRequest{
   110  			Datacenter:  "dc1",
   111  			IntentionID: ixn.Intention.ID,
   112  		}
   113  		var resp structs.IndexedIntentions
   114  		assert.Nil(msgpackrpc.CallWithCodec(codec, "Intention.Get", req, &resp))
   115  		assert.Len(resp.Intentions, 1)
   116  		actual := resp.Intentions[0]
   117  		assert.Equal(structs.IntentionSourceConsul, actual.SourceType)
   118  	}
   119  }
   120  
   121  // Shouldn't be able to create with an ID set
   122  func TestIntentionApply_createWithID(t *testing.T) {
   123  	t.Parallel()
   124  
   125  	assert := assert.New(t)
   126  	dir1, s1 := testServer(t)
   127  	defer os.RemoveAll(dir1)
   128  	defer s1.Shutdown()
   129  	codec := rpcClient(t, s1)
   130  	defer codec.Close()
   131  
   132  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
   133  
   134  	// Setup a basic record to create
   135  	ixn := structs.IntentionRequest{
   136  		Datacenter: "dc1",
   137  		Op:         structs.IntentionOpCreate,
   138  		Intention: &structs.Intention{
   139  			ID:         generateUUID(),
   140  			SourceName: "test",
   141  		},
   142  	}
   143  	var reply string
   144  
   145  	// Create
   146  	err := msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply)
   147  	assert.NotNil(err)
   148  	assert.Contains(err, "ID must be empty")
   149  }
   150  
   151  // Test basic updating
   152  func TestIntentionApply_updateGood(t *testing.T) {
   153  	t.Parallel()
   154  
   155  	assert := assert.New(t)
   156  	dir1, s1 := testServer(t)
   157  	defer os.RemoveAll(dir1)
   158  	defer s1.Shutdown()
   159  	codec := rpcClient(t, s1)
   160  	defer codec.Close()
   161  
   162  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
   163  
   164  	// Setup a basic record to create
   165  	ixn := structs.IntentionRequest{
   166  		Datacenter: "dc1",
   167  		Op:         structs.IntentionOpCreate,
   168  		Intention: &structs.Intention{
   169  			SourceNS:        structs.IntentionDefaultNamespace,
   170  			SourceName:      "test",
   171  			DestinationNS:   structs.IntentionDefaultNamespace,
   172  			DestinationName: "test",
   173  			Action:          structs.IntentionActionAllow,
   174  			SourceType:      structs.IntentionSourceConsul,
   175  			Meta:            map[string]string{},
   176  		},
   177  	}
   178  	var reply string
   179  
   180  	// Create
   181  	assert.Nil(msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply))
   182  	assert.NotEmpty(reply)
   183  
   184  	// Read CreatedAt
   185  	var createdAt time.Time
   186  	ixn.Intention.ID = reply
   187  	{
   188  		req := &structs.IntentionQueryRequest{
   189  			Datacenter:  "dc1",
   190  			IntentionID: ixn.Intention.ID,
   191  		}
   192  		var resp structs.IndexedIntentions
   193  		assert.Nil(msgpackrpc.CallWithCodec(codec, "Intention.Get", req, &resp))
   194  		assert.Len(resp.Intentions, 1)
   195  		actual := resp.Intentions[0]
   196  		createdAt = actual.CreatedAt
   197  	}
   198  
   199  	// Sleep a bit so that the updated at will definitely be different, not much
   200  	time.Sleep(1 * time.Millisecond)
   201  
   202  	// Update
   203  	ixn.Op = structs.IntentionOpUpdate
   204  	ixn.Intention.ID = reply
   205  	ixn.Intention.SourceName = "*"
   206  	assert.Nil(msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply))
   207  
   208  	// Read
   209  	ixn.Intention.ID = reply
   210  	{
   211  		req := &structs.IntentionQueryRequest{
   212  			Datacenter:  "dc1",
   213  			IntentionID: ixn.Intention.ID,
   214  		}
   215  		var resp structs.IndexedIntentions
   216  		assert.Nil(msgpackrpc.CallWithCodec(codec, "Intention.Get", req, &resp))
   217  		assert.Len(resp.Intentions, 1)
   218  		actual := resp.Intentions[0]
   219  		assert.Equal(createdAt, actual.CreatedAt)
   220  		assert.WithinDuration(time.Now(), actual.UpdatedAt, 5*time.Second)
   221  
   222  		actual.CreateIndex, actual.ModifyIndex = 0, 0
   223  		actual.CreatedAt = ixn.Intention.CreatedAt
   224  		actual.UpdatedAt = ixn.Intention.UpdatedAt
   225  		ixn.Intention.UpdatePrecedence()
   226  		assert.Equal(ixn.Intention, actual)
   227  	}
   228  }
   229  
   230  // Shouldn't be able to update a non-existent intention
   231  func TestIntentionApply_updateNonExist(t *testing.T) {
   232  	t.Parallel()
   233  
   234  	assert := assert.New(t)
   235  	dir1, s1 := testServer(t)
   236  	defer os.RemoveAll(dir1)
   237  	defer s1.Shutdown()
   238  	codec := rpcClient(t, s1)
   239  	defer codec.Close()
   240  
   241  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
   242  
   243  	// Setup a basic record to create
   244  	ixn := structs.IntentionRequest{
   245  		Datacenter: "dc1",
   246  		Op:         structs.IntentionOpUpdate,
   247  		Intention: &structs.Intention{
   248  			ID:         generateUUID(),
   249  			SourceName: "test",
   250  		},
   251  	}
   252  	var reply string
   253  
   254  	// Create
   255  	err := msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply)
   256  	assert.NotNil(err)
   257  	assert.Contains(err, "Cannot modify non-existent intention")
   258  }
   259  
   260  // Test basic deleting
   261  func TestIntentionApply_deleteGood(t *testing.T) {
   262  	t.Parallel()
   263  
   264  	assert := assert.New(t)
   265  	dir1, s1 := testServer(t)
   266  	defer os.RemoveAll(dir1)
   267  	defer s1.Shutdown()
   268  	codec := rpcClient(t, s1)
   269  	defer codec.Close()
   270  
   271  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
   272  
   273  	// Setup a basic record to create
   274  	ixn := structs.IntentionRequest{
   275  		Datacenter: "dc1",
   276  		Op:         structs.IntentionOpCreate,
   277  		Intention: &structs.Intention{
   278  			SourceNS:        "test",
   279  			SourceName:      "test",
   280  			DestinationNS:   "test",
   281  			DestinationName: "test",
   282  			Action:          structs.IntentionActionAllow,
   283  		},
   284  	}
   285  	var reply string
   286  
   287  	// Create
   288  	assert.Nil(msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply))
   289  	assert.NotEmpty(reply)
   290  
   291  	// Delete
   292  	ixn.Op = structs.IntentionOpDelete
   293  	ixn.Intention.ID = reply
   294  	assert.Nil(msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply))
   295  
   296  	// Read
   297  	ixn.Intention.ID = reply
   298  	{
   299  		req := &structs.IntentionQueryRequest{
   300  			Datacenter:  "dc1",
   301  			IntentionID: ixn.Intention.ID,
   302  		}
   303  		var resp structs.IndexedIntentions
   304  		err := msgpackrpc.CallWithCodec(codec, "Intention.Get", req, &resp)
   305  		assert.NotNil(err)
   306  		assert.Contains(err, ErrIntentionNotFound.Error())
   307  	}
   308  }
   309  
   310  // Test apply with a deny ACL
   311  func TestIntentionApply_aclDeny(t *testing.T) {
   312  	t.Parallel()
   313  
   314  	assert := assert.New(t)
   315  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
   316  		c.ACLDatacenter = "dc1"
   317  		c.ACLsEnabled = true
   318  		c.ACLMasterToken = "root"
   319  		c.ACLDefaultPolicy = "deny"
   320  	})
   321  	defer os.RemoveAll(dir1)
   322  	defer s1.Shutdown()
   323  	codec := rpcClient(t, s1)
   324  	defer codec.Close()
   325  
   326  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
   327  
   328  	// Create an ACL with write permissions
   329  	var token string
   330  	{
   331  		var rules = `
   332  service "foo" {
   333  	policy = "deny"
   334  	intentions = "write"
   335  }`
   336  
   337  		req := structs.ACLRequest{
   338  			Datacenter: "dc1",
   339  			Op:         structs.ACLSet,
   340  			ACL: structs.ACL{
   341  				Name:  "User token",
   342  				Type:  structs.ACLTokenTypeClient,
   343  				Rules: rules,
   344  			},
   345  			WriteRequest: structs.WriteRequest{Token: "root"},
   346  		}
   347  		assert.Nil(msgpackrpc.CallWithCodec(codec, "ACL.Apply", &req, &token))
   348  	}
   349  
   350  	// Setup a basic record to create
   351  	ixn := structs.IntentionRequest{
   352  		Datacenter: "dc1",
   353  		Op:         structs.IntentionOpCreate,
   354  		Intention:  structs.TestIntention(t),
   355  	}
   356  	ixn.Intention.DestinationName = "foobar"
   357  
   358  	// Create without a token should error since default deny
   359  	var reply string
   360  	err := msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply)
   361  	assert.True(acl.IsErrPermissionDenied(err))
   362  
   363  	// Now add the token and try again.
   364  	ixn.WriteRequest.Token = token
   365  	assert.Nil(msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply))
   366  
   367  	// Read
   368  	ixn.Intention.ID = reply
   369  	{
   370  		req := &structs.IntentionQueryRequest{
   371  			Datacenter:   "dc1",
   372  			IntentionID:  ixn.Intention.ID,
   373  			QueryOptions: structs.QueryOptions{Token: "root"},
   374  		}
   375  		var resp structs.IndexedIntentions
   376  		assert.Nil(msgpackrpc.CallWithCodec(codec, "Intention.Get", req, &resp))
   377  		assert.Len(resp.Intentions, 1)
   378  		actual := resp.Intentions[0]
   379  		assert.Equal(resp.Index, actual.ModifyIndex)
   380  
   381  		actual.CreateIndex, actual.ModifyIndex = 0, 0
   382  		actual.CreatedAt = ixn.Intention.CreatedAt
   383  		actual.UpdatedAt = ixn.Intention.UpdatedAt
   384  		ixn.Intention.UpdatePrecedence()
   385  		assert.Equal(ixn.Intention, actual)
   386  	}
   387  }
   388  
   389  // Test apply with delete and a default deny ACL
   390  func TestIntentionApply_aclDelete(t *testing.T) {
   391  	t.Parallel()
   392  
   393  	assert := assert.New(t)
   394  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
   395  		c.ACLDatacenter = "dc1"
   396  		c.ACLsEnabled = true
   397  		c.ACLMasterToken = "root"
   398  		c.ACLDefaultPolicy = "deny"
   399  	})
   400  	defer os.RemoveAll(dir1)
   401  	defer s1.Shutdown()
   402  	codec := rpcClient(t, s1)
   403  	defer codec.Close()
   404  
   405  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
   406  
   407  	// Create an ACL with write permissions
   408  	var token string
   409  	{
   410  		var rules = `
   411  service "foo" {
   412  	policy = "deny"
   413  	intentions = "write"
   414  }`
   415  
   416  		req := structs.ACLRequest{
   417  			Datacenter: "dc1",
   418  			Op:         structs.ACLSet,
   419  			ACL: structs.ACL{
   420  				Name:  "User token",
   421  				Type:  structs.ACLTokenTypeClient,
   422  				Rules: rules,
   423  			},
   424  			WriteRequest: structs.WriteRequest{Token: "root"},
   425  		}
   426  		assert.Nil(msgpackrpc.CallWithCodec(codec, "ACL.Apply", &req, &token))
   427  	}
   428  
   429  	// Setup a basic record to create
   430  	ixn := structs.IntentionRequest{
   431  		Datacenter: "dc1",
   432  		Op:         structs.IntentionOpCreate,
   433  		Intention:  structs.TestIntention(t),
   434  	}
   435  	ixn.Intention.DestinationName = "foobar"
   436  	ixn.WriteRequest.Token = token
   437  
   438  	// Create
   439  	var reply string
   440  	assert.Nil(msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply))
   441  
   442  	// Try to do a delete with no token; this should get rejected.
   443  	ixn.Op = structs.IntentionOpDelete
   444  	ixn.Intention.ID = reply
   445  	ixn.WriteRequest.Token = ""
   446  	err := msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply)
   447  	assert.True(acl.IsErrPermissionDenied(err))
   448  
   449  	// Try again with the original token. This should go through.
   450  	ixn.WriteRequest.Token = token
   451  	assert.Nil(msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply))
   452  
   453  	// Verify it is gone
   454  	{
   455  		req := &structs.IntentionQueryRequest{
   456  			Datacenter:  "dc1",
   457  			IntentionID: ixn.Intention.ID,
   458  		}
   459  		var resp structs.IndexedIntentions
   460  		err := msgpackrpc.CallWithCodec(codec, "Intention.Get", req, &resp)
   461  		assert.NotNil(err)
   462  		assert.Contains(err.Error(), ErrIntentionNotFound.Error())
   463  	}
   464  }
   465  
   466  // Test apply with update and a default deny ACL
   467  func TestIntentionApply_aclUpdate(t *testing.T) {
   468  	t.Parallel()
   469  
   470  	assert := assert.New(t)
   471  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
   472  		c.ACLDatacenter = "dc1"
   473  		c.ACLsEnabled = true
   474  		c.ACLMasterToken = "root"
   475  		c.ACLDefaultPolicy = "deny"
   476  	})
   477  	defer os.RemoveAll(dir1)
   478  	defer s1.Shutdown()
   479  	codec := rpcClient(t, s1)
   480  	defer codec.Close()
   481  
   482  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
   483  
   484  	// Create an ACL with write permissions
   485  	var token string
   486  	{
   487  		var rules = `
   488  service "foo" {
   489  	policy = "deny"
   490  	intentions = "write"
   491  }`
   492  
   493  		req := structs.ACLRequest{
   494  			Datacenter: "dc1",
   495  			Op:         structs.ACLSet,
   496  			ACL: structs.ACL{
   497  				Name:  "User token",
   498  				Type:  structs.ACLTokenTypeClient,
   499  				Rules: rules,
   500  			},
   501  			WriteRequest: structs.WriteRequest{Token: "root"},
   502  		}
   503  		assert.Nil(msgpackrpc.CallWithCodec(codec, "ACL.Apply", &req, &token))
   504  	}
   505  
   506  	// Setup a basic record to create
   507  	ixn := structs.IntentionRequest{
   508  		Datacenter: "dc1",
   509  		Op:         structs.IntentionOpCreate,
   510  		Intention:  structs.TestIntention(t),
   511  	}
   512  	ixn.Intention.DestinationName = "foobar"
   513  	ixn.WriteRequest.Token = token
   514  
   515  	// Create
   516  	var reply string
   517  	assert.Nil(msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply))
   518  
   519  	// Try to do an update without a token; this should get rejected.
   520  	ixn.Op = structs.IntentionOpUpdate
   521  	ixn.Intention.ID = reply
   522  	ixn.WriteRequest.Token = ""
   523  	err := msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply)
   524  	assert.True(acl.IsErrPermissionDenied(err))
   525  
   526  	// Try again with the original token; this should go through.
   527  	ixn.WriteRequest.Token = token
   528  	assert.Nil(msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply))
   529  }
   530  
   531  // Test apply with a management token
   532  func TestIntentionApply_aclManagement(t *testing.T) {
   533  	t.Parallel()
   534  
   535  	assert := assert.New(t)
   536  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
   537  		c.ACLDatacenter = "dc1"
   538  		c.ACLsEnabled = true
   539  		c.ACLMasterToken = "root"
   540  		c.ACLDefaultPolicy = "deny"
   541  	})
   542  	defer os.RemoveAll(dir1)
   543  	defer s1.Shutdown()
   544  	codec := rpcClient(t, s1)
   545  	defer codec.Close()
   546  
   547  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
   548  
   549  	// Setup a basic record to create
   550  	ixn := structs.IntentionRequest{
   551  		Datacenter: "dc1",
   552  		Op:         structs.IntentionOpCreate,
   553  		Intention:  structs.TestIntention(t),
   554  	}
   555  	ixn.Intention.DestinationName = "foobar"
   556  	ixn.WriteRequest.Token = "root"
   557  
   558  	// Create
   559  	var reply string
   560  	assert.Nil(msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply))
   561  	ixn.Intention.ID = reply
   562  
   563  	// Update
   564  	ixn.Op = structs.IntentionOpUpdate
   565  	assert.Nil(msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply))
   566  
   567  	// Delete
   568  	ixn.Op = structs.IntentionOpDelete
   569  	assert.Nil(msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply))
   570  }
   571  
   572  // Test update changing the name where an ACL won't allow it
   573  func TestIntentionApply_aclUpdateChange(t *testing.T) {
   574  	t.Parallel()
   575  
   576  	assert := assert.New(t)
   577  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
   578  		c.ACLDatacenter = "dc1"
   579  		c.ACLsEnabled = true
   580  		c.ACLMasterToken = "root"
   581  		c.ACLDefaultPolicy = "deny"
   582  	})
   583  	defer os.RemoveAll(dir1)
   584  	defer s1.Shutdown()
   585  	codec := rpcClient(t, s1)
   586  	defer codec.Close()
   587  
   588  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
   589  
   590  	// Create an ACL with write permissions
   591  	var token string
   592  	{
   593  		var rules = `
   594  service "foo" {
   595  	policy = "deny"
   596  	intentions = "write"
   597  }`
   598  
   599  		req := structs.ACLRequest{
   600  			Datacenter: "dc1",
   601  			Op:         structs.ACLSet,
   602  			ACL: structs.ACL{
   603  				Name:  "User token",
   604  				Type:  structs.ACLTokenTypeClient,
   605  				Rules: rules,
   606  			},
   607  			WriteRequest: structs.WriteRequest{Token: "root"},
   608  		}
   609  		assert.Nil(msgpackrpc.CallWithCodec(codec, "ACL.Apply", &req, &token))
   610  	}
   611  
   612  	// Setup a basic record to create
   613  	ixn := structs.IntentionRequest{
   614  		Datacenter: "dc1",
   615  		Op:         structs.IntentionOpCreate,
   616  		Intention:  structs.TestIntention(t),
   617  	}
   618  	ixn.Intention.DestinationName = "bar"
   619  	ixn.WriteRequest.Token = "root"
   620  
   621  	// Create
   622  	var reply string
   623  	assert.Nil(msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply))
   624  
   625  	// Try to do an update without a token; this should get rejected.
   626  	ixn.Op = structs.IntentionOpUpdate
   627  	ixn.Intention.ID = reply
   628  	ixn.Intention.DestinationName = "foo"
   629  	ixn.WriteRequest.Token = token
   630  	err := msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply)
   631  	assert.True(acl.IsErrPermissionDenied(err))
   632  }
   633  
   634  // Test reading with ACLs
   635  func TestIntentionGet_acl(t *testing.T) {
   636  	t.Parallel()
   637  
   638  	assert := assert.New(t)
   639  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
   640  		c.ACLDatacenter = "dc1"
   641  		c.ACLsEnabled = true
   642  		c.ACLMasterToken = "root"
   643  		c.ACLDefaultPolicy = "deny"
   644  	})
   645  	defer os.RemoveAll(dir1)
   646  	defer s1.Shutdown()
   647  	codec := rpcClient(t, s1)
   648  	defer codec.Close()
   649  
   650  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
   651  
   652  	// Create an ACL with service write permissions. This will grant
   653  	// intentions read.
   654  	var token string
   655  	{
   656  		var rules = `
   657  service "foo" {
   658  	policy = "write"
   659  }`
   660  
   661  		req := structs.ACLRequest{
   662  			Datacenter: "dc1",
   663  			Op:         structs.ACLSet,
   664  			ACL: structs.ACL{
   665  				Name:  "User token",
   666  				Type:  structs.ACLTokenTypeClient,
   667  				Rules: rules,
   668  			},
   669  			WriteRequest: structs.WriteRequest{Token: "root"},
   670  		}
   671  		assert.Nil(msgpackrpc.CallWithCodec(codec, "ACL.Apply", &req, &token))
   672  	}
   673  
   674  	// Setup a basic record to create
   675  	ixn := structs.IntentionRequest{
   676  		Datacenter: "dc1",
   677  		Op:         structs.IntentionOpCreate,
   678  		Intention:  structs.TestIntention(t),
   679  	}
   680  	ixn.Intention.DestinationName = "foobar"
   681  	ixn.WriteRequest.Token = "root"
   682  
   683  	// Create
   684  	var reply string
   685  	assert.Nil(msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply))
   686  	ixn.Intention.ID = reply
   687  
   688  	// Read without token should be error
   689  	{
   690  		req := &structs.IntentionQueryRequest{
   691  			Datacenter:  "dc1",
   692  			IntentionID: ixn.Intention.ID,
   693  		}
   694  
   695  		var resp structs.IndexedIntentions
   696  		err := msgpackrpc.CallWithCodec(codec, "Intention.Get", req, &resp)
   697  		assert.True(acl.IsErrPermissionDenied(err))
   698  		assert.Len(resp.Intentions, 0)
   699  	}
   700  
   701  	// Read with token should work
   702  	{
   703  		req := &structs.IntentionQueryRequest{
   704  			Datacenter:   "dc1",
   705  			IntentionID:  ixn.Intention.ID,
   706  			QueryOptions: structs.QueryOptions{Token: token},
   707  		}
   708  
   709  		var resp structs.IndexedIntentions
   710  		assert.Nil(msgpackrpc.CallWithCodec(codec, "Intention.Get", req, &resp))
   711  		assert.Len(resp.Intentions, 1)
   712  	}
   713  }
   714  
   715  func TestIntentionList(t *testing.T) {
   716  	t.Parallel()
   717  
   718  	assert := assert.New(t)
   719  	dir1, s1 := testServer(t)
   720  	defer os.RemoveAll(dir1)
   721  	defer s1.Shutdown()
   722  
   723  	codec := rpcClient(t, s1)
   724  	defer codec.Close()
   725  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
   726  
   727  	// Test with no intentions inserted yet
   728  	{
   729  		req := &structs.DCSpecificRequest{
   730  			Datacenter: "dc1",
   731  		}
   732  		var resp structs.IndexedIntentions
   733  		assert.Nil(msgpackrpc.CallWithCodec(codec, "Intention.List", req, &resp))
   734  		assert.NotNil(resp.Intentions)
   735  		assert.Len(resp.Intentions, 0)
   736  	}
   737  }
   738  
   739  // Test listing with ACLs
   740  func TestIntentionList_acl(t *testing.T) {
   741  	t.Parallel()
   742  
   743  	assert := assert.New(t)
   744  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
   745  		c.ACLDatacenter = "dc1"
   746  		c.ACLsEnabled = true
   747  		c.ACLMasterToken = "root"
   748  		c.ACLDefaultPolicy = "deny"
   749  	})
   750  	defer os.RemoveAll(dir1)
   751  	defer s1.Shutdown()
   752  	codec := rpcClient(t, s1)
   753  	defer codec.Close()
   754  
   755  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
   756  
   757  	// Create an ACL with service write permissions. This will grant
   758  	// intentions read.
   759  	var token string
   760  	{
   761  		var rules = `
   762  service "foo" {
   763  	policy = "write"
   764  }`
   765  
   766  		req := structs.ACLRequest{
   767  			Datacenter: "dc1",
   768  			Op:         structs.ACLSet,
   769  			ACL: structs.ACL{
   770  				Name:  "User token",
   771  				Type:  structs.ACLTokenTypeClient,
   772  				Rules: rules,
   773  			},
   774  			WriteRequest: structs.WriteRequest{Token: "root"},
   775  		}
   776  		assert.Nil(msgpackrpc.CallWithCodec(codec, "ACL.Apply", &req, &token))
   777  	}
   778  
   779  	// Create a few records
   780  	for _, name := range []string{"foobar", "bar", "baz"} {
   781  		ixn := structs.IntentionRequest{
   782  			Datacenter: "dc1",
   783  			Op:         structs.IntentionOpCreate,
   784  			Intention:  structs.TestIntention(t),
   785  		}
   786  		ixn.Intention.DestinationName = name
   787  		ixn.WriteRequest.Token = "root"
   788  
   789  		// Create
   790  		var reply string
   791  		assert.Nil(msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply))
   792  	}
   793  
   794  	// Test with no token
   795  	{
   796  		req := &structs.DCSpecificRequest{
   797  			Datacenter: "dc1",
   798  		}
   799  		var resp structs.IndexedIntentions
   800  		assert.Nil(msgpackrpc.CallWithCodec(codec, "Intention.List", req, &resp))
   801  		assert.Len(resp.Intentions, 0)
   802  	}
   803  
   804  	// Test with management token
   805  	{
   806  		req := &structs.DCSpecificRequest{
   807  			Datacenter:   "dc1",
   808  			QueryOptions: structs.QueryOptions{Token: "root"},
   809  		}
   810  		var resp structs.IndexedIntentions
   811  		assert.Nil(msgpackrpc.CallWithCodec(codec, "Intention.List", req, &resp))
   812  		assert.Len(resp.Intentions, 3)
   813  	}
   814  
   815  	// Test with user token
   816  	{
   817  		req := &structs.DCSpecificRequest{
   818  			Datacenter:   "dc1",
   819  			QueryOptions: structs.QueryOptions{Token: token},
   820  		}
   821  		var resp structs.IndexedIntentions
   822  		assert.Nil(msgpackrpc.CallWithCodec(codec, "Intention.List", req, &resp))
   823  		assert.Len(resp.Intentions, 1)
   824  	}
   825  }
   826  
   827  // Test basic matching. We don't need to exhaustively test inputs since this
   828  // is tested in the agent/consul/state package.
   829  func TestIntentionMatch_good(t *testing.T) {
   830  	t.Parallel()
   831  
   832  	assert := assert.New(t)
   833  	dir1, s1 := testServer(t)
   834  	defer os.RemoveAll(dir1)
   835  	defer s1.Shutdown()
   836  	codec := rpcClient(t, s1)
   837  	defer codec.Close()
   838  
   839  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
   840  
   841  	// Create some records
   842  	{
   843  		insert := [][]string{
   844  			{"foo", "*", "foo", "*"},
   845  			{"foo", "*", "foo", "bar"},
   846  			{"foo", "*", "foo", "baz"}, // shouldn't match
   847  			{"foo", "*", "bar", "bar"}, // shouldn't match
   848  			{"foo", "*", "bar", "*"},   // shouldn't match
   849  			{"foo", "*", "*", "*"},
   850  			{"bar", "*", "foo", "bar"}, // duplicate destination different source
   851  		}
   852  
   853  		for _, v := range insert {
   854  			ixn := structs.IntentionRequest{
   855  				Datacenter: "dc1",
   856  				Op:         structs.IntentionOpCreate,
   857  				Intention: &structs.Intention{
   858  					SourceNS:        v[0],
   859  					SourceName:      v[1],
   860  					DestinationNS:   v[2],
   861  					DestinationName: v[3],
   862  					Action:          structs.IntentionActionAllow,
   863  				},
   864  			}
   865  
   866  			// Create
   867  			var reply string
   868  			assert.Nil(msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply))
   869  		}
   870  	}
   871  
   872  	// Match
   873  	req := &structs.IntentionQueryRequest{
   874  		Datacenter: "dc1",
   875  		Match: &structs.IntentionQueryMatch{
   876  			Type: structs.IntentionMatchDestination,
   877  			Entries: []structs.IntentionMatchEntry{
   878  				{
   879  					Namespace: "foo",
   880  					Name:      "bar",
   881  				},
   882  			},
   883  		},
   884  	}
   885  	var resp structs.IndexedIntentionMatches
   886  	assert.Nil(msgpackrpc.CallWithCodec(codec, "Intention.Match", req, &resp))
   887  	assert.Len(resp.Matches, 1)
   888  
   889  	expected := [][]string{
   890  		{"bar", "*", "foo", "bar"},
   891  		{"foo", "*", "foo", "bar"},
   892  		{"foo", "*", "foo", "*"},
   893  		{"foo", "*", "*", "*"},
   894  	}
   895  	var actual [][]string
   896  	for _, ixn := range resp.Matches[0] {
   897  		actual = append(actual, []string{
   898  			ixn.SourceNS,
   899  			ixn.SourceName,
   900  			ixn.DestinationNS,
   901  			ixn.DestinationName,
   902  		})
   903  	}
   904  	assert.Equal(expected, actual)
   905  }
   906  
   907  // Test matching with ACLs
   908  func TestIntentionMatch_acl(t *testing.T) {
   909  	t.Parallel()
   910  
   911  	assert := assert.New(t)
   912  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
   913  		c.ACLDatacenter = "dc1"
   914  		c.ACLsEnabled = true
   915  		c.ACLMasterToken = "root"
   916  		c.ACLDefaultPolicy = "deny"
   917  	})
   918  	defer os.RemoveAll(dir1)
   919  	defer s1.Shutdown()
   920  	codec := rpcClient(t, s1)
   921  	defer codec.Close()
   922  
   923  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
   924  
   925  	// Create an ACL with service write permissions. This will grant
   926  	// intentions read.
   927  	var token string
   928  	{
   929  		var rules = `
   930  service "bar" {
   931  	policy = "write"
   932  }`
   933  
   934  		req := structs.ACLRequest{
   935  			Datacenter: "dc1",
   936  			Op:         structs.ACLSet,
   937  			ACL: structs.ACL{
   938  				Name:  "User token",
   939  				Type:  structs.ACLTokenTypeClient,
   940  				Rules: rules,
   941  			},
   942  			WriteRequest: structs.WriteRequest{Token: "root"},
   943  		}
   944  		assert.Nil(msgpackrpc.CallWithCodec(codec, "ACL.Apply", &req, &token))
   945  	}
   946  
   947  	// Create some records
   948  	{
   949  		insert := [][]string{
   950  			{"foo", "*"},
   951  			{"foo", "bar"},
   952  			{"foo", "baz"}, // shouldn't match
   953  			{"bar", "bar"}, // shouldn't match
   954  			{"bar", "*"},   // shouldn't match
   955  			{"*", "*"},
   956  		}
   957  
   958  		for _, v := range insert {
   959  			ixn := structs.IntentionRequest{
   960  				Datacenter: "dc1",
   961  				Op:         structs.IntentionOpCreate,
   962  				Intention:  structs.TestIntention(t),
   963  			}
   964  			ixn.Intention.DestinationNS = v[0]
   965  			ixn.Intention.DestinationName = v[1]
   966  			ixn.WriteRequest.Token = "root"
   967  
   968  			// Create
   969  			var reply string
   970  			assert.Nil(msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply))
   971  		}
   972  	}
   973  
   974  	// Test with no token
   975  	{
   976  		req := &structs.IntentionQueryRequest{
   977  			Datacenter: "dc1",
   978  			Match: &structs.IntentionQueryMatch{
   979  				Type: structs.IntentionMatchDestination,
   980  				Entries: []structs.IntentionMatchEntry{
   981  					{
   982  						Namespace: "foo",
   983  						Name:      "bar",
   984  					},
   985  				},
   986  			},
   987  		}
   988  		var resp structs.IndexedIntentionMatches
   989  		err := msgpackrpc.CallWithCodec(codec, "Intention.Match", req, &resp)
   990  		assert.True(acl.IsErrPermissionDenied(err))
   991  		assert.Len(resp.Matches, 0)
   992  	}
   993  
   994  	// Test with proper token
   995  	{
   996  		req := &structs.IntentionQueryRequest{
   997  			Datacenter: "dc1",
   998  			Match: &structs.IntentionQueryMatch{
   999  				Type: structs.IntentionMatchDestination,
  1000  				Entries: []structs.IntentionMatchEntry{
  1001  					{
  1002  						Namespace: "foo",
  1003  						Name:      "bar",
  1004  					},
  1005  				},
  1006  			},
  1007  			QueryOptions: structs.QueryOptions{Token: token},
  1008  		}
  1009  		var resp structs.IndexedIntentionMatches
  1010  		assert.Nil(msgpackrpc.CallWithCodec(codec, "Intention.Match", req, &resp))
  1011  		assert.Len(resp.Matches, 1)
  1012  
  1013  		expected := [][]string{{"foo", "bar"}, {"foo", "*"}, {"*", "*"}}
  1014  		var actual [][]string
  1015  		for _, ixn := range resp.Matches[0] {
  1016  			actual = append(actual, []string{ixn.DestinationNS, ixn.DestinationName})
  1017  		}
  1018  
  1019  		assert.Equal(expected, actual)
  1020  	}
  1021  }
  1022  
  1023  // Test the Check method defaults to allow with no ACL set.
  1024  func TestIntentionCheck_defaultNoACL(t *testing.T) {
  1025  	t.Parallel()
  1026  
  1027  	require := require.New(t)
  1028  	dir1, s1 := testServer(t)
  1029  	defer os.RemoveAll(dir1)
  1030  	defer s1.Shutdown()
  1031  	codec := rpcClient(t, s1)
  1032  	defer codec.Close()
  1033  
  1034  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
  1035  
  1036  	// Test
  1037  	req := &structs.IntentionQueryRequest{
  1038  		Datacenter: "dc1",
  1039  		Check: &structs.IntentionQueryCheck{
  1040  			SourceNS:        "foo",
  1041  			SourceName:      "bar",
  1042  			DestinationNS:   "foo",
  1043  			DestinationName: "qux",
  1044  			SourceType:      structs.IntentionSourceConsul,
  1045  		},
  1046  	}
  1047  	var resp structs.IntentionQueryCheckResponse
  1048  	require.Nil(msgpackrpc.CallWithCodec(codec, "Intention.Check", req, &resp))
  1049  	require.True(resp.Allowed)
  1050  }
  1051  
  1052  // Test the Check method defaults to deny with whitelist ACLs.
  1053  func TestIntentionCheck_defaultACLDeny(t *testing.T) {
  1054  	t.Parallel()
  1055  
  1056  	require := require.New(t)
  1057  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
  1058  		c.ACLDatacenter = "dc1"
  1059  		c.ACLsEnabled = true
  1060  		c.ACLMasterToken = "root"
  1061  		c.ACLDefaultPolicy = "deny"
  1062  	})
  1063  	defer os.RemoveAll(dir1)
  1064  	defer s1.Shutdown()
  1065  	codec := rpcClient(t, s1)
  1066  	defer codec.Close()
  1067  
  1068  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
  1069  
  1070  	// Check
  1071  	req := &structs.IntentionQueryRequest{
  1072  		Datacenter: "dc1",
  1073  		Check: &structs.IntentionQueryCheck{
  1074  			SourceNS:        "foo",
  1075  			SourceName:      "bar",
  1076  			DestinationNS:   "foo",
  1077  			DestinationName: "qux",
  1078  			SourceType:      structs.IntentionSourceConsul,
  1079  		},
  1080  	}
  1081  	req.Token = "root"
  1082  	var resp structs.IntentionQueryCheckResponse
  1083  	require.Nil(msgpackrpc.CallWithCodec(codec, "Intention.Check", req, &resp))
  1084  	require.False(resp.Allowed)
  1085  }
  1086  
  1087  // Test the Check method defaults to deny with blacklist ACLs.
  1088  func TestIntentionCheck_defaultACLAllow(t *testing.T) {
  1089  	t.Parallel()
  1090  
  1091  	require := require.New(t)
  1092  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
  1093  		c.ACLDatacenter = "dc1"
  1094  		c.ACLsEnabled = true
  1095  		c.ACLMasterToken = "root"
  1096  		c.ACLDefaultPolicy = "allow"
  1097  	})
  1098  	defer os.RemoveAll(dir1)
  1099  	defer s1.Shutdown()
  1100  	codec := rpcClient(t, s1)
  1101  	defer codec.Close()
  1102  
  1103  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
  1104  
  1105  	// Check
  1106  	req := &structs.IntentionQueryRequest{
  1107  		Datacenter: "dc1",
  1108  		Check: &structs.IntentionQueryCheck{
  1109  			SourceNS:        "foo",
  1110  			SourceName:      "bar",
  1111  			DestinationNS:   "foo",
  1112  			DestinationName: "qux",
  1113  			SourceType:      structs.IntentionSourceConsul,
  1114  		},
  1115  	}
  1116  	req.Token = "root"
  1117  	var resp structs.IntentionQueryCheckResponse
  1118  	require.Nil(msgpackrpc.CallWithCodec(codec, "Intention.Check", req, &resp))
  1119  	require.True(resp.Allowed)
  1120  }
  1121  
  1122  // Test the Check method requires service:read permission.
  1123  func TestIntentionCheck_aclDeny(t *testing.T) {
  1124  	t.Parallel()
  1125  
  1126  	require := require.New(t)
  1127  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
  1128  		c.ACLDatacenter = "dc1"
  1129  		c.ACLsEnabled = true
  1130  		c.ACLMasterToken = "root"
  1131  		c.ACLDefaultPolicy = "deny"
  1132  	})
  1133  	defer os.RemoveAll(dir1)
  1134  	defer s1.Shutdown()
  1135  	codec := rpcClient(t, s1)
  1136  	defer codec.Close()
  1137  
  1138  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
  1139  
  1140  	// Create an ACL with service read permissions. This will grant permission.
  1141  	var token string
  1142  	{
  1143  		var rules = `
  1144  service "bar" {
  1145  	policy = "read"
  1146  }`
  1147  
  1148  		req := structs.ACLRequest{
  1149  			Datacenter: "dc1",
  1150  			Op:         structs.ACLSet,
  1151  			ACL: structs.ACL{
  1152  				Name:  "User token",
  1153  				Type:  structs.ACLTokenTypeClient,
  1154  				Rules: rules,
  1155  			},
  1156  			WriteRequest: structs.WriteRequest{Token: "root"},
  1157  		}
  1158  		require.Nil(msgpackrpc.CallWithCodec(codec, "ACL.Apply", &req, &token))
  1159  	}
  1160  
  1161  	// Check
  1162  	req := &structs.IntentionQueryRequest{
  1163  		Datacenter: "dc1",
  1164  		Check: &structs.IntentionQueryCheck{
  1165  			SourceNS:        "foo",
  1166  			SourceName:      "qux",
  1167  			DestinationNS:   "foo",
  1168  			DestinationName: "baz",
  1169  			SourceType:      structs.IntentionSourceConsul,
  1170  		},
  1171  	}
  1172  	req.Token = token
  1173  	var resp structs.IntentionQueryCheckResponse
  1174  	err := msgpackrpc.CallWithCodec(codec, "Intention.Check", req, &resp)
  1175  	require.True(acl.IsErrPermissionDenied(err))
  1176  }
  1177  
  1178  // Test the Check method returns allow/deny properly.
  1179  func TestIntentionCheck_match(t *testing.T) {
  1180  	t.Parallel()
  1181  
  1182  	require := require.New(t)
  1183  	dir1, s1 := testServerWithConfig(t, func(c *Config) {
  1184  		c.ACLDatacenter = "dc1"
  1185  		c.ACLsEnabled = true
  1186  		c.ACLMasterToken = "root"
  1187  		c.ACLDefaultPolicy = "deny"
  1188  	})
  1189  	defer os.RemoveAll(dir1)
  1190  	defer s1.Shutdown()
  1191  	codec := rpcClient(t, s1)
  1192  	defer codec.Close()
  1193  
  1194  	testrpc.WaitForLeader(t, s1.RPC, "dc1")
  1195  
  1196  	// Create an ACL with service read permissions. This will grant permission.
  1197  	var token string
  1198  	{
  1199  		var rules = `
  1200  service "bar" {
  1201  	policy = "read"
  1202  }`
  1203  
  1204  		req := structs.ACLRequest{
  1205  			Datacenter: "dc1",
  1206  			Op:         structs.ACLSet,
  1207  			ACL: structs.ACL{
  1208  				Name:  "User token",
  1209  				Type:  structs.ACLTokenTypeClient,
  1210  				Rules: rules,
  1211  			},
  1212  			WriteRequest: structs.WriteRequest{Token: "root"},
  1213  		}
  1214  		require.Nil(msgpackrpc.CallWithCodec(codec, "ACL.Apply", &req, &token))
  1215  	}
  1216  
  1217  	// Create some intentions
  1218  	{
  1219  		insert := [][]string{
  1220  			{"foo", "*", "foo", "*"},
  1221  			{"foo", "*", "foo", "bar"},
  1222  			{"bar", "*", "foo", "bar"}, // duplicate destination different source
  1223  		}
  1224  
  1225  		for _, v := range insert {
  1226  			ixn := structs.IntentionRequest{
  1227  				Datacenter: "dc1",
  1228  				Op:         structs.IntentionOpCreate,
  1229  				Intention: &structs.Intention{
  1230  					SourceNS:        v[0],
  1231  					SourceName:      v[1],
  1232  					DestinationNS:   v[2],
  1233  					DestinationName: v[3],
  1234  					Action:          structs.IntentionActionAllow,
  1235  				},
  1236  			}
  1237  			ixn.WriteRequest.Token = "root"
  1238  
  1239  			// Create
  1240  			var reply string
  1241  			require.Nil(msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply))
  1242  		}
  1243  	}
  1244  
  1245  	// Check
  1246  	req := &structs.IntentionQueryRequest{
  1247  		Datacenter: "dc1",
  1248  		Check: &structs.IntentionQueryCheck{
  1249  			SourceNS:        "foo",
  1250  			SourceName:      "qux",
  1251  			DestinationNS:   "foo",
  1252  			DestinationName: "bar",
  1253  			SourceType:      structs.IntentionSourceConsul,
  1254  		},
  1255  	}
  1256  	req.Token = token
  1257  	var resp structs.IntentionQueryCheckResponse
  1258  	require.Nil(msgpackrpc.CallWithCodec(codec, "Intention.Check", req, &resp))
  1259  	require.True(resp.Allowed)
  1260  
  1261  	// Test no match for sanity
  1262  	{
  1263  		req := &structs.IntentionQueryRequest{
  1264  			Datacenter: "dc1",
  1265  			Check: &structs.IntentionQueryCheck{
  1266  				SourceNS:        "baz",
  1267  				SourceName:      "qux",
  1268  				DestinationNS:   "foo",
  1269  				DestinationName: "bar",
  1270  				SourceType:      structs.IntentionSourceConsul,
  1271  			},
  1272  		}
  1273  		req.Token = token
  1274  		var resp structs.IntentionQueryCheckResponse
  1275  		require.Nil(msgpackrpc.CallWithCodec(codec, "Intention.Check", req, &resp))
  1276  		require.False(resp.Allowed)
  1277  	}
  1278  }