diff --git a/jobs/nats-tls/spec b/jobs/nats-tls/spec index 777b98ec..577abc20 100644 --- a/jobs/nats-tls/spec +++ b/jobs/nats-tls/spec @@ -40,6 +40,7 @@ provides: - nats.cluster_port - nats.external.tls.ca - nats.write_deadline + - nats.migrate_server.port consumes: - name: nats diff --git a/jobs/nats/spec b/jobs/nats/spec index 9421d597..fd673ee3 100644 --- a/jobs/nats/spec +++ b/jobs/nats/spec @@ -39,6 +39,10 @@ provides: - nats.cluster_port - nats.write_deadline - nats.disable + - nats.migrate_server.port + - nats.migrate_server.tls.ca: + - nats.migrate_server.tls.certificate: + - nats.migrate_server.tls.private_key: consumes: - name: nats diff --git a/src/code.cloudfoundry.org/nats-v2-migrate/integration/nats_wrapper_test.go b/src/code.cloudfoundry.org/nats-v2-migrate/integration/nats_wrapper_test.go index c5c5388b..3b82d057 100644 --- a/src/code.cloudfoundry.org/nats-v2-migrate/integration/nats_wrapper_test.go +++ b/src/code.cloudfoundry.org/nats-v2-migrate/integration/nats_wrapper_test.go @@ -16,6 +16,7 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "github.com/onsi/gomega/gbytes" "github.com/onsi/gomega/gexec" "code.cloudfoundry.org/cf-networking-helpers/certauthority" @@ -448,6 +449,35 @@ var _ = Describe("NATS Wrapper", func() { }) }) }) + + Describe("/shutdown-gracefully", func() { + + BeforeEach(func() { + cfg = config.Config{ + Bootstrap: true, + NATSMigratePort: int(natsMigratorPort), + Address: "127.0.0.1", + NATSPort: int(natsPort), + NATSInstances: []string{}, + NATSMigrateServers: []string{}, + NATSV1BinPath: natsV1File, + NATSV2BinPath: natsV2File, + } + GenerateCerts(&cfg) + StartServer(cfg) + client = CreateTLSClient(cfg) + }) + + It("sends a signal to NATS to shutdown", func() { + resp, err := client.Post(fmt.Sprintf("https://%s/shutdown-gracefully", address), "application/json", nil) + Expect(err).ToNot(HaveOccurred()) + Expect(resp.StatusCode).To(Equal(200)) + Eventually(session).Should(gbytes.Say("graceful-shutdown-triggered")) + Eventually(session).Should(gbytes.Say("signalled-nats")) + // the nats in this test is fake so it doesn't actually exit + // which means that wrapper doesn't shut down in this test + }) + }) }) func VerifyTCPConnection(address string) error { diff --git a/src/code.cloudfoundry.org/nats-v2-migrate/nats-wrapper/main.go b/src/code.cloudfoundry.org/nats-v2-migrate/nats-wrapper/main.go index 33a2fdb5..e9989d02 100644 --- a/src/code.cloudfoundry.org/nats-v2-migrate/nats-wrapper/main.go +++ b/src/code.cloudfoundry.org/nats-v2-migrate/nats-wrapper/main.go @@ -68,6 +68,14 @@ func main() { sm := http.NewServeMux() sm.HandleFunc("/info", httpServer.Info) sm.HandleFunc("/migrate", httpServer.Migrate) + sm.HandleFunc("POST /shutdown-gracefully", func(w http.ResponseWriter, r *http.Request) { + logger.Info("graceful-shutdown-triggered") + w.WriteHeader(http.StatusOK) + // #nosec G104 - don't handle error writing http response. at best, we could log it and be susceptible to DoS's filling up disks with logs + w.Write(nil) + syscall.Kill(os.Getpid(), syscall.SIGINT) // SIGINT stops the nats server gracefully + return + }) migrateServer := http_server.NewTLSServer(fmt.Sprintf("0.0.0.0:%d", cfg.NATSMigratePort), sm, tlsConfig)