diff --git a/agent/agent_endpoint_test.go b/agent/agent_endpoint_test.go index 62d095fba..adef1b237 100644 --- a/agent/agent_endpoint_test.go +++ b/agent/agent_endpoint_test.go @@ -1519,6 +1519,40 @@ func TestAgent_RegisterService_UnmanagedConnectProxyInvalid(t *testing.T) { assert.False(ok) } +// Tests agent registration of a service that is connect native. +func TestAgent_RegisterService_ConnectNative(t *testing.T) { + t.Parallel() + + assert := assert.New(t) + a := NewTestAgent(t.Name(), "") + defer a.Shutdown() + + // Register a proxy. Note that the destination doesn't exist here on + // this agent or in the catalog at all. This is intended and part + // of the design. + args := &structs.ServiceDefinition{ + Name: "web", + Port: 8000, + Check: structs.CheckType{ + TTL: 15 * time.Second, + }, + Connect: &structs.ServiceDefinitionConnect{ + Native: true, + }, + } + + req, _ := http.NewRequest("PUT", "/v1/agent/service/register", jsonReader(args)) + resp := httptest.NewRecorder() + obj, err := a.srv.AgentRegisterService(resp, req) + assert.Nil(err) + assert.Nil(obj) + + // Ensure the service + svc, ok := a.State.Services()["web"] + assert.True(ok, "has service") + assert.True(svc.ConnectNative) +} + func TestAgent_DeregisterService(t *testing.T) { t.Parallel() a := NewTestAgent(t.Name(), "") diff --git a/agent/structs/service_definition.go b/agent/structs/service_definition.go index 506015649..26d158529 100644 --- a/agent/structs/service_definition.go +++ b/agent/structs/service_definition.go @@ -36,6 +36,9 @@ func (s *ServiceDefinition) NodeService() *NodeService { EnableTagOverride: s.EnableTagOverride, ProxyDestination: s.ProxyDestination, } + if s.Connect != nil { + ns.ConnectNative = s.Connect.Native + } if ns.ID == "" && ns.Service != "" { ns.ID = ns.Service } @@ -83,10 +86,17 @@ func (s *ServiceDefinition) Validate() error { var result error if s.Kind == ServiceKindTypical { - if s.Connect != nil && s.Connect.Proxy != nil { - if s.Port == 0 { - result = multierror.Append(result, fmt.Errorf( - "Services with a Connect managed proxy must have a port set")) + if s.Connect != nil { + if s.Connect.Proxy != nil { + if s.Connect.Native { + result = multierror.Append(result, fmt.Errorf( + "Services that are Connect native may not have a proxy configuration")) + } + + if s.Port == 0 { + result = multierror.Append(result, fmt.Errorf( + "Services with a Connect managed proxy must have a port set")) + } } } } @@ -120,7 +130,9 @@ func (s *ServiceDefinition) CheckTypes() (checks CheckTypes, err error) { // Note this is duplicated in config.ServiceConnect and needs to be kept in // sync. type ServiceDefinitionConnect struct { - // TODO(banks) add way to specify that the app is connect-native + // Native is true when this service can natively understand Connect. + Native bool + // Proxy configures a connect proxy instance for the service Proxy *ServiceDefinitionConnectProxy } diff --git a/agent/structs/service_definition_test.go b/agent/structs/service_definition_test.go index c73cff217..54c711db7 100644 --- a/agent/structs/service_definition_test.go +++ b/agent/structs/service_definition_test.go @@ -89,6 +89,18 @@ func TestServiceDefinitionValidate(t *testing.T) { }, "must have a port", }, + + { + "managed proxy with native set", + func(x *ServiceDefinition) { + x.Port = 8080 + x.Connect = &ServiceDefinitionConnect{ + Native: true, + Proxy: &ServiceDefinitionConnectProxy{}, + } + }, + "may not have a proxy", + }, } for _, tc := range cases {