Always allow updating the exposed service and differentiate by namespace

This commit is contained in:
Kyle Havlovitz 2020-06-09 11:09:53 -07:00
parent c466551ec1
commit 1a561b78ca
2 changed files with 66 additions and 36 deletions

View File

@ -124,62 +124,63 @@ func (c *cmd) Run(args []string) int {
} }
listenerIdx := -1 listenerIdx := -1
serviceIdx := -1
newService := api.IngressService{
Name: svc,
Namespace: svcNamespace,
Hosts: c.hosts,
}
for i, listener := range ingressConf.Listeners { for i, listener := range ingressConf.Listeners {
// Make sure the service isn't already exposed in this gateway // Find the listener for the specified port, if one exists.
for _, service := range listener.Services { if listener.Port != c.port {
if service.Name == svc && listener.Port == c.port { continue
c.UI.Output(fmt.Sprintf("Service %q already exposed through listener with port %d", svc, listener.Port))
goto CREATE_INTENTION
}
} }
// If there's already a listener for the given port, make sure the protocol matches. // Make sure the given protocol matches the existing one.
if listener.Port == c.port { listenerIdx = i
listenerIdx = i if listener.Protocol != c.protocol {
if listener.Protocol != c.protocol { c.UI.Error(fmt.Sprintf("Listener on port %d already configured with conflicting protocol %q", listener.Port, listener.Protocol))
c.UI.Error(fmt.Sprintf("Listener on port %d already configured with conflicting protocol %q", listener.Port, listener.Protocol)) return 1
return 1 }
// Make sure the service isn't already exposed in this gateway
for j, service := range listener.Services {
if service.Name == svc && service.Namespace == svcNamespace {
serviceIdx = j
c.UI.Output(fmt.Sprintf("Updating service definition for %q on listener with port %d", c.service, listener.Port))
break
} }
} }
} }
// Add a service to the existing listener for the port if one exists, or make a new listener. // Add a service to the existing listener for the port if one exists, or make a new listener.
if listenerIdx >= 0 { if listenerIdx >= 0 {
ingressConf.Listeners[listenerIdx].Services = append(ingressConf.Listeners[listenerIdx].Services, api.IngressService{ if serviceIdx >= 0 {
Name: svc, ingressConf.Listeners[listenerIdx].Services[serviceIdx] = newService
Namespace: svcNamespace, } else {
Hosts: c.hosts, ingressConf.Listeners[listenerIdx].Services = append(ingressConf.Listeners[listenerIdx].Services, newService)
}) }
} else { } else {
ingressConf.Listeners = append(ingressConf.Listeners, api.IngressListener{ ingressConf.Listeners = append(ingressConf.Listeners, api.IngressListener{
Port: c.port, Port: c.port,
Protocol: c.protocol, Protocol: c.protocol,
Services: []api.IngressService{ Services: []api.IngressService{newService},
{
Name: svc,
Namespace: svcNamespace,
Hosts: c.hosts,
},
},
}) })
} }
// Write the updated config entry using a check-and-set, so it fails if the entry // Write the updated config entry using a check-and-set, so it fails if the entry
// has been changed since we looked it up. // has been changed since we looked it up.
{ succeeded, _, err := client.ConfigEntries().CAS(ingressConf, ingressConf.GetModifyIndex(), nil)
succeeded, _, err := client.ConfigEntries().CAS(ingressConf, ingressConf.GetModifyIndex(), nil) if err != nil {
if err != nil { c.UI.Error(fmt.Sprintf("Error writing ingress config entry: %v", err))
c.UI.Error(fmt.Sprintf("Error writing ingress config entry: %v", err)) return 1
return 1
}
if !succeeded {
c.UI.Error("Ingress config entry was changed while attempting to update, please try again.")
return 1
}
c.UI.Output(fmt.Sprintf("Successfully updated config entry for ingress service %q", gateway))
} }
if !succeeded {
c.UI.Error("Ingress config entry was changed while attempting to update, please try again.")
return 1
}
c.UI.Output(fmt.Sprintf("Successfully updated config entry for ingress service %q", gateway))
CREATE_INTENTION:
// Check for an existing intention. // Check for an existing intention.
ixnFinder := finder.Finder{Client: client} ixnFinder := finder.Finder{Client: client}
existing, err := ixnFinder.Find(c.ingressGateway, c.service) existing, err := ixnFinder.Find(c.ingressGateway, c.service)

View File

@ -300,4 +300,33 @@ func TestConnectExpose_existingConfig(t *testing.T) {
ingressConf.ModifyIndex = entry.GetModifyIndex() ingressConf.ModifyIndex = entry.GetModifyIndex()
require.Equal(ingressConf, entry) require.Equal(ingressConf, entry)
} }
// Update the bar service and add a custom host.
testrpc.WaitForTestAgent(t, a.RPC, "dc1")
{
ui := cli.NewMockUi()
c := New(ui)
args := []string{
"-http-addr=" + a.HTTPAddr(),
"-service=bar",
"-ingress-gateway=ingress",
"-port=9999",
"-protocol=http",
"-host=bar.com",
}
code := c.Run(args)
if code != 0 {
t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String())
}
// Make sure the ingress config was updated and existing services preserved.
entry, _, err := client.ConfigEntries().Get(api.IngressGateway, "ingress", nil)
require.NoError(err)
ingressConf.Listeners[1].Services[0].Hosts = []string{"bar.com"}
ingressConf.CreateIndex = entry.GetCreateIndex()
ingressConf.ModifyIndex = entry.GetModifyIndex()
require.Equal(ingressConf, entry)
}
} }