fix(txn api): missing proxy config in registering proxy service (#14471)

* fix(txn api): missing proxy config in registering proxy service
This commit is contained in:
cskh 2022-09-02 14:28:05 -04:00 committed by GitHub
parent 8f5ddec17c
commit 0f7d4efac3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 165 additions and 14 deletions

View File

@ -185,6 +185,7 @@ func (s *HTTPHandlers) convertOps(resp http.ResponseWriter, req *http.Request) (
Address: node.Address,
Datacenter: node.Datacenter,
TaggedAddresses: node.TaggedAddresses,
PeerName: node.PeerName,
Meta: node.Meta,
RaftIndex: structs.RaftIndex{
ModifyIndex: node.ModifyIndex,
@ -207,6 +208,7 @@ func (s *HTTPHandlers) convertOps(resp http.ResponseWriter, req *http.Request) (
Service: structs.NodeService{
ID: svc.ID,
Service: svc.Service,
Kind: structs.ServiceKind(svc.Kind),
Tags: svc.Tags,
Address: svc.Address,
Meta: svc.Meta,
@ -226,6 +228,39 @@ func (s *HTTPHandlers) convertOps(resp http.ResponseWriter, req *http.Request) (
},
},
}
if svc.Proxy != nil {
out.Service.Service.Proxy = structs.ConnectProxyConfig{}
t := &out.Service.Service.Proxy
if svc.Proxy.DestinationServiceName != "" {
t.DestinationServiceName = svc.Proxy.DestinationServiceName
}
if svc.Proxy.DestinationServiceID != "" {
t.DestinationServiceID = svc.Proxy.DestinationServiceID
}
if svc.Proxy.LocalServiceAddress != "" {
t.LocalServiceAddress = svc.Proxy.LocalServiceAddress
}
if svc.Proxy.LocalServicePort != 0 {
t.LocalServicePort = svc.Proxy.LocalServicePort
}
if svc.Proxy.LocalServiceSocketPath != "" {
t.LocalServiceSocketPath = svc.Proxy.LocalServiceSocketPath
}
if svc.Proxy.MeshGateway.Mode != "" {
t.MeshGateway.Mode = structs.MeshGatewayMode(svc.Proxy.MeshGateway.Mode)
}
if svc.Proxy.TransparentProxy != nil {
if svc.Proxy.TransparentProxy.DialedDirectly {
t.TransparentProxy.DialedDirectly = svc.Proxy.TransparentProxy.DialedDirectly
}
if svc.Proxy.TransparentProxy.OutboundListenerPort != 0 {
t.TransparentProxy.OutboundListenerPort = svc.Proxy.TransparentProxy.OutboundListenerPort
}
}
}
opsRPC = append(opsRPC, out)
case in.Check != nil:
@ -265,6 +300,8 @@ func (s *HTTPHandlers) convertOps(resp http.ResponseWriter, req *http.Request) (
ServiceID: check.ServiceID,
ServiceName: check.ServiceName,
ServiceTags: check.ServiceTags,
PeerName: check.PeerName,
ExposedPort: check.ExposedPort,
Definition: structs.HealthCheckDefinition{
HTTP: check.Definition.HTTP,
TLSServerName: check.Definition.TLSServerName,

View File

@ -585,6 +585,7 @@ func TestTxnEndpoint_UpdateCheck(t *testing.T) {
"Output": "success",
"ServiceID": "",
"ServiceName": "",
"ExposedPort": 5678,
"Definition": {
"IntervalDuration": "15s",
"TimeoutDuration": "15s",
@ -600,12 +601,8 @@ func TestTxnEndpoint_UpdateCheck(t *testing.T) {
req, _ := http.NewRequest("PUT", "/v1/txn", buf)
resp := httptest.NewRecorder()
obj, err := a.srv.Txn(resp, req)
if err != nil {
t.Fatalf("err: %v", err)
}
if resp.Code != 200 {
t.Fatalf("expected 200, got %d", resp.Code)
}
require.NoError(t, err)
require.Equal(t, 200, resp.Code, resp.Body)
txnResp, ok := obj.(structs.TxnResponse)
if !ok {
@ -662,12 +659,13 @@ func TestTxnEndpoint_UpdateCheck(t *testing.T) {
},
&structs.TxnResult{
Check: &structs.HealthCheck{
Node: a.config.NodeName,
CheckID: "nodecheck",
Name: "Node http check",
Status: api.HealthPassing,
Notes: "Http based health check",
Output: "success",
Node: a.config.NodeName,
CheckID: "nodecheck",
Name: "Node http check",
Status: api.HealthPassing,
Notes: "Http based health check",
Output: "success",
ExposedPort: 5678,
Definition: structs.HealthCheckDefinition{
Interval: 15 * time.Second,
Timeout: 15 * time.Second,
@ -686,3 +684,117 @@ func TestTxnEndpoint_UpdateCheck(t *testing.T) {
}
assert.Equal(t, expected, txnResp)
}
func TestTxnEndpoint_NodeService(t *testing.T) {
if testing.Short() {
t.Skip("too slow for testing.Short")
}
t.Parallel()
a := NewTestAgent(t, "")
defer a.Shutdown()
testrpc.WaitForTestAgent(t, a.RPC, "dc1")
// Make sure the fields of a check are handled correctly when both creating and
// updating, and test both sets of duration fields to ensure backwards compatibility.
buf := bytes.NewBuffer([]byte(fmt.Sprintf(`
[
{
"Service": {
"Verb": "set",
"Node": "%s",
"Service": {
"Service": "test",
"Port": 4444
}
}
},
{
"Service": {
"Verb": "set",
"Node": "%s",
"Service": {
"Service": "test-sidecar-proxy",
"Port": 20000,
"Kind": "connect-proxy",
"Proxy": {
"DestinationServiceName": "test",
"DestinationServiceID": "test",
"LocalServiceAddress": "127.0.0.1",
"LocalServicePort": 4444,
"upstreams": [
{
"DestinationName": "fake-backend",
"LocalBindPort": 25001
}
]
}
}
}
}
]
`, a.config.NodeName, a.config.NodeName)))
req, _ := http.NewRequest("PUT", "/v1/txn", buf)
resp := httptest.NewRecorder()
obj, err := a.srv.Txn(resp, req)
require.NoError(t, err)
require.Equal(t, 200, resp.Code)
txnResp, ok := obj.(structs.TxnResponse)
if !ok {
t.Fatalf("bad type: %T", obj)
}
require.Equal(t, 2, len(txnResp.Results))
index := txnResp.Results[0].Service.ModifyIndex
expected := structs.TxnResponse{
Results: structs.TxnResults{
&structs.TxnResult{
Service: &structs.NodeService{
Service: "test",
ID: "test",
Port: 4444,
Weights: &structs.Weights{
Passing: 1,
Warning: 1,
},
RaftIndex: structs.RaftIndex{
CreateIndex: index,
ModifyIndex: index,
},
EnterpriseMeta: *structs.DefaultEnterpriseMetaInDefaultPartition(),
},
},
&structs.TxnResult{
Service: &structs.NodeService{
Service: "test-sidecar-proxy",
ID: "test-sidecar-proxy",
Port: 20000,
Kind: "connect-proxy",
Weights: &structs.Weights{
Passing: 1,
Warning: 1,
},
Proxy: structs.ConnectProxyConfig{
DestinationServiceName: "test",
DestinationServiceID: "test",
LocalServiceAddress: "127.0.0.1",
LocalServicePort: 4444,
},
TaggedAddresses: map[string]structs.ServiceAddress{
"consul-virtual": {
Address: "240.0.0.1",
Port: 20000,
},
},
RaftIndex: structs.RaftIndex{
CreateIndex: index,
ModifyIndex: index,
},
EnterpriseMeta: *structs.DefaultEnterpriseMetaInDefaultPartition(),
},
},
},
}
assert.Equal(t, expected, txnResp)
}

View File

@ -20,6 +20,7 @@ type Node struct {
CreateIndex uint64
ModifyIndex uint64
Partition string `json:",omitempty"`
PeerName string `json:",omitempty"`
}
type ServiceAddress struct {

View File

@ -45,6 +45,8 @@ type HealthCheck struct {
Type string
Namespace string `json:",omitempty"`
Partition string `json:",omitempty"`
ExposedPort int
PeerName string `json:",omitempty"`
Definition HealthCheckDefinition
@ -176,8 +178,7 @@ type HealthChecks []*HealthCheck
// attached, this function determines the best representative of the status as
// as single string using the following heuristic:
//
// maintenance > critical > warning > passing
//
// maintenance > critical > warning > passing
func (c HealthChecks) AggregatedStatus() string {
var passing, warning, critical, maintenance bool
for _, check := range c {