agent/consul: set default intention SourceType, validate it

This commit is contained in:
Mitchell Hashimoto 2018-03-03 09:55:27 -08:00
parent d92993f75b
commit ab4ea3efb4
No known key found for this signature in database
GPG Key ID: 744E147AA52F5B0A
5 changed files with 83 additions and 0 deletions

View File

@ -86,6 +86,11 @@ func (s *Intention) Apply(
// We always update the updatedat field. This has no effect for deletion.
args.Intention.UpdatedAt = time.Now()
// Default source type
if args.Intention.SourceType == "" {
args.Intention.SourceType = structs.IntentionSourceConsul
}
// Until we support namespaces, we force all namespaces to be default
if args.Intention.SourceNS == "" {
args.Intention.SourceNS = structs.IntentionDefaultNamespace

View File

@ -33,6 +33,7 @@ func TestIntentionApply_new(t *testing.T) {
DestinationNS: structs.IntentionDefaultNamespace,
DestinationName: "test",
Action: structs.IntentionActionAllow,
SourceType: structs.IntentionSourceConsul,
Meta: map[string]string{},
},
}
@ -93,6 +94,61 @@ func TestIntentionApply_new(t *testing.T) {
}
}
// Test the source type defaults
func TestIntentionApply_defaultSourceType(t *testing.T) {
t.Parallel()
dir1, s1 := testServer(t)
defer os.RemoveAll(dir1)
defer s1.Shutdown()
codec := rpcClient(t, s1)
defer codec.Close()
testrpc.WaitForLeader(t, s1.RPC, "dc1")
// Setup a basic record to create
ixn := structs.IntentionRequest{
Datacenter: "dc1",
Op: structs.IntentionOpCreate,
Intention: &structs.Intention{
SourceNS: structs.IntentionDefaultNamespace,
SourceName: "test",
DestinationNS: structs.IntentionDefaultNamespace,
DestinationName: "test",
Action: structs.IntentionActionAllow,
},
}
var reply string
// Create
if err := msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply); err != nil {
t.Fatalf("err: %v", err)
}
if reply == "" {
t.Fatal("reply should be non-empty")
}
// Read
ixn.Intention.ID = reply
{
req := &structs.IntentionQueryRequest{
Datacenter: "dc1",
IntentionID: ixn.Intention.ID,
}
var resp structs.IndexedIntentions
if err := msgpackrpc.CallWithCodec(codec, "Intention.Get", req, &resp); err != nil {
t.Fatalf("err: %v", err)
}
if len(resp.Intentions) != 1 {
t.Fatalf("bad: %v", resp)
}
actual := resp.Intentions[0]
if actual.SourceType != structs.IntentionSourceConsul {
t.Fatalf("bad:\n\n%#v\n\n%#v", actual, ixn.Intention)
}
}
}
// Shouldn't be able to create with an ID set
func TestIntentionApply_createWithID(t *testing.T) {
t.Parallel()
@ -143,6 +199,7 @@ func TestIntentionApply_updateGood(t *testing.T) {
DestinationNS: structs.IntentionDefaultNamespace,
DestinationName: "test",
Action: structs.IntentionActionAllow,
SourceType: structs.IntentionSourceConsul,
Meta: map[string]string{},
},
}

View File

@ -147,6 +147,13 @@ func (x *Intention) Validate() error {
"Action must be set to 'allow' or 'deny'"))
}
switch x.SourceType {
case IntentionSourceConsul:
default:
result = multierror.Append(result, fmt.Errorf(
"SourceType must be set to 'consul'"))
}
return result
}

View File

@ -92,6 +92,18 @@ func TestIntentionValidate(t *testing.T) {
},
"follow wildcard",
},
{
"SourceType is not set",
func(x *Intention) { x.SourceType = "" },
"SourceType must",
},
{
"SourceType is other",
func(x *Intention) { x.SourceType = IntentionSourceType("other") },
"SourceType must",
},
}
for _, tc := range cases {

View File

@ -11,5 +11,7 @@ func TestIntention(t testing.T) *Intention {
SourceName: "api",
DestinationNS: "eng",
DestinationName: "db",
Action: IntentionActionAllow,
SourceType: IntentionSourceConsul,
}
}