func (s *S) TestListCertRoutes(c *C) { api := s.newTestAPIServer(c) defer api.Close() srv1 := httptest.NewServer(httpTestHandler("1")) defer srv1.Close() l := s.newHTTPListener(c) defer l.Close() domain := "oof.example.org" r := addHTTPRouteForDomain(domain, c, l) tlsCert, err := tlscert.Generate([]string{domain}) c.Assert(err, IsNil) cert := &router.Certificate{ Routes: []string{r.ID}, Cert: tlsCert.Cert, Key: tlsCert.PrivateKey, } err = api.CreateCert(cert) c.Assert(err, IsNil) gotRoutes, err := api.ListCertRoutes(cert.ID) c.Assert(err, IsNil) c.Assert(len(gotRoutes), Equals, 1) gotRoute := gotRoutes[0] c.Assert(gotRoute.ID, Equals, r.ID) c.Assert(gotRoute.Certificate, IsNil) }
func (a *GenTLSCertAction) Run(s *State) (err error) { data := &tlscert.Cert{} s.StepData[a.ID] = data a.CACert = interpolate(s, a.CACert) a.Cert = interpolate(s, a.Cert) a.PrivateKey = interpolate(s, a.PrivateKey) if a.CACert != "" && a.Cert != "" && a.PrivateKey != "" { data.CACert = a.CACert data.Cert = a.Cert data.PrivateKey = a.PrivateKey // calculate cert pin b, _ := pem.Decode([]byte(data.Cert)) sha := sha256.Sum256(b.Bytes) data.Pin = base64.StdEncoding.EncodeToString(sha[:]) return nil } for i, h := range a.Hosts { a.Hosts[i] = interpolate(s, h) } c, err := tlscert.Generate(a.Hosts) if err != nil { return err } data.CACert = c.CACert data.Cert = c.Cert data.Pin = c.Pin data.PrivateKey = c.PrivateKey return err }
func (s *S) TestListCerts(c *C) { api := s.newTestAPIServer(c) defer api.Close() srv1 := httptest.NewServer(httpTestHandler("1")) defer srv1.Close() l := s.newHTTPListener(c) defer l.Close() domain := "oof.example.org" r := addHTTPRouteForDomain(domain, c, l) tlsCert, err := tlscert.Generate([]string{domain}) c.Assert(err, IsNil) cert := &router.Certificate{ Routes: []string{r.ID}, Cert: tlsCert.Cert, Key: tlsCert.PrivateKey, } err = api.CreateCert(cert) c.Assert(err, IsNil) gotCerts, err := api.ListCerts() c.Assert(err, IsNil) c.Assert(len(gotCerts), Equals, 2) gotCert := gotCerts[1] // the first cert was created with the route c.Assert(gotCert.ID, Equals, cert.ID) c.Assert(gotCert.Cert, Equals, cert.Cert) c.Assert(gotCert.Key, Equals, cert.Key) c.Assert(gotCert.Routes, DeepEquals, cert.Routes) }
func (s *S) TestAddHTTPRouteWithInvalidCert(c *C) { l := s.newHTTPListener(c) defer l.Close() c1, _ := tlscert.Generate([]string{"1.example.com"}) c2, _ := tlscert.Generate([]string{"2.example.com"}) err := l.AddRoute(router.HTTPRoute{ Domain: "example.com", Service: "test", Certificate: &router.Certificate{ Cert: c1.Cert, Key: c2.PrivateKey, }, }.ToRoute()) c.Assert(err, Not(IsNil)) }
func refreshTLSConfigForDomain(domain string) *tlscert.Cert { tlsCertsMux.Lock() defer tlsCertsMux.Unlock() domain = normalizeDomain(domain) c, err := tlscert.Generate([]string{domain}) if err != nil { panic(err) } tlsCerts[domain] = c return c }
func (m *migration) generateTLSCert() (*tlscert.Cert, error) { hosts := []string{ m.dm.Domain, fmt.Sprintf("*.%s", m.dm.Domain), } cert, err := tlscert.Generate(hosts) if err != nil { return nil, err } if _, err := m.db.Query("UPDATE domain_migrations SET tls_cert = $1 WHERE migration_id = $2", cert, m.dm.ID); err != nil { return nil, err } return cert, nil }
func tlsConfigForDomain(domain string) ([]byte, []byte) { tlsCertsMux.Lock() defer tlsCertsMux.Unlock() domain = strings.ToLower(domain) if d, _, err := net.SplitHostPort(domain); err == nil { domain = d } if strings.HasSuffix(domain, ".example.com") { domain = "example.com" } if c, ok := tlsCerts[domain]; ok { return []byte(c.CACert), []byte(c.PrivateKey) } c, err := tlscert.Generate([]string{domain}) if err != nil { panic(err) } tlsCerts[domain] = c return []byte(c.Cert), []byte(c.PrivateKey) }
func tlsConfigForDomain(domain string) *tlscert.Cert { tlsCertsMux.Lock() defer tlsCertsMux.Unlock() domain = normalizeDomain(domain) parts := strings.SplitAfter(domain, ".") wildcard := "*." for i := 1; i < len(parts); i++ { wildcard += parts[i] } if c, ok := tlsCerts[domain]; ok { return c } if c, ok := tlsCerts[wildcard]; ok { return c } c, err := tlscert.Generate([]string{domain}) if err != nil { panic(err) } tlsCerts[domain] = c return c }
func (s *CLISuite) TestRoute(t *c.C) { client := s.controllerClient(t) app := s.newCliTestApp(t) defer app.cleanup() // The router API does not currently give us a "read your own writes" // guarantee, so we must retry a few times if we don't get the expected // result. assertRouteContains := func(str string, contained bool) { var res *CmdResult attempt.Strategy{ Total: 10 * time.Second, Delay: 500 * time.Millisecond, }.Run(func() error { res = app.flynn("route") if contained == strings.Contains(res.Output, str) { return nil } return errors.New("unexpected output") }) if contained { t.Assert(res, SuccessfulOutputContains, str) } else { t.Assert(res, c.Not(SuccessfulOutputContains), str) } } // flynn route add http route := random.String(32) + ".dev" newRoute := app.flynn("route", "add", "http", route) t.Assert(newRoute, Succeeds) routeID := strings.TrimSpace(newRoute.Output) assertRouteContains(routeID, true) // ensure sticky and leader flags default to not set routes, err := client.RouteList(app.name) t.Assert(err, c.IsNil) var found bool for _, r := range routes { if fmt.Sprintf("%s/%s", r.Type, r.ID) != routeID { continue } t.Assert(r.Sticky, c.Equals, false) t.Assert(r.Leader, c.Equals, false) found = true break } t.Assert(found, c.Equals, true, c.Commentf("didn't find route")) // flynn route add http --sticky --leader route = random.String(32) + ".dev" newRoute = app.flynn("route", "add", "http", "--sticky", route, "--leader") t.Assert(newRoute, Succeeds) routeID = strings.TrimSpace(newRoute.Output) assertRouteContains(routeID, true) // duplicate http route dupRoute := app.flynn("route", "add", "http", "--sticky", route) t.Assert(dupRoute, c.Not(Succeeds)) t.Assert(dupRoute.Output, c.Equals, "conflict: Duplicate route\n") // ensure sticky and leader flags are set routes, err = client.RouteList(app.name) t.Assert(err, c.IsNil) for _, r := range routes { if fmt.Sprintf("%s/%s", r.Type, r.ID) != routeID { continue } t.Assert(r.Sticky, c.Equals, true) t.Assert(r.Leader, c.Equals, true) found = true break } t.Assert(found, c.Equals, true, c.Commentf("didn't find route")) // flynn route update --no-sticky newRoute = app.flynn("route", "update", routeID, "--no-sticky") t.Assert(newRoute, Succeeds) r, err := client.GetRoute(app.id, routeID) t.Assert(err, c.IsNil) t.Assert(r.Sticky, c.Equals, false) // flynn route update --no-leader newRoute = app.flynn("route", "update", routeID, "--no-leader") t.Assert(newRoute, Succeeds) r, err = client.GetRoute(app.id, routeID) t.Assert(err, c.IsNil) t.Assert(r.Leader, c.Equals, false) // flynn route update --service newRoute = app.flynn("route", "update", routeID, "--service", "foo") t.Assert(newRoute, Succeeds) r, err = client.GetRoute(app.id, routeID) t.Assert(err, c.IsNil) t.Assert(r.Service, c.Equals, "foo") t.Assert(r.Sticky, c.Equals, false) // flynn route update --sticky newRoute = app.flynn("route", "update", routeID, "--sticky") t.Assert(newRoute, Succeeds) r, err = client.GetRoute(app.id, routeID) t.Assert(err, c.IsNil) t.Assert(r.Sticky, c.Equals, true) t.Assert(r.Service, c.Equals, "foo") // flynn route update --leader newRoute = app.flynn("route", "update", routeID, "--leader") t.Assert(newRoute, Succeeds) r, err = client.GetRoute(app.id, routeID) t.Assert(err, c.IsNil) t.Assert(r.Leader, c.Equals, true) t.Assert(r.Service, c.Equals, "foo") // flynn route add domain path pathRoute := app.flynn("route", "add", "http", route+"/path/") t.Assert(pathRoute, Succeeds) pathRouteID := strings.TrimSpace(pathRoute.Output) assertRouteContains(pathRouteID, true) // flynn route add domain path duplicate dupRoute = app.flynn("route", "add", "http", route+"/path/") t.Assert(dupRoute, c.Not(Succeeds)) t.Assert(dupRoute.Output, c.Equals, "conflict: Duplicate route\n") // flynn route add domain path without trailing should correct to trailing noTrailingRoute := app.flynn("route", "add", "http", route+"/path2") t.Assert(noTrailingRoute, Succeeds) noTrailingRouteID := strings.TrimSpace(noTrailingRoute.Output) assertRouteContains(noTrailingRouteID, true) // flynn route should show the corrected trailing path assertRouteContains("/path2/", true) // flynn route remove should fail because of dependent route delFail := app.flynn("route", "remove", routeID) t.Assert(delFail, c.Not(Succeeds)) // But removing the dependent route and then the default route should work t.Assert(app.flynn("route", "remove", pathRouteID), Succeeds) assertRouteContains(pathRouteID, false) t.Assert(app.flynn("route", "remove", noTrailingRouteID), Succeeds) assertRouteContains(noTrailingRouteID, false) t.Assert(app.flynn("route", "remove", routeID), Succeeds) assertRouteContains(routeID, false) // flynn route add tcp tcpRoute := app.flynn("route", "add", "tcp") t.Assert(tcpRoute, Succeeds) routeID = strings.Split(tcpRoute.Output, " ")[0] assertRouteContains(routeID, true) // flynn route add tcp --port portRoute := app.flynn("route", "add", "tcp", "--port", "9999") t.Assert(portRoute, Succeeds) routeID = strings.Split(portRoute.Output, " ")[0] port := strings.Split(portRoute.Output, " ")[4] t.Assert(port, c.Equals, "9999\n") assertRouteContains(routeID, true) // flynn route update --service portRoute = app.flynn("route", "update", routeID, "--service", "foo") t.Assert(portRoute, Succeeds) r, err = client.GetRoute(app.id, routeID) t.Assert(err, c.IsNil) t.Assert(r.Service, c.Equals, "foo") // flynn route remove t.Assert(app.flynn("route", "remove", routeID), Succeeds) assertRouteContains(routeID, false) writeTemp := func(data, prefix string) (string, error) { f, err := ioutil.TempFile(os.TempDir(), fmt.Sprintf("flynn-test-%s", prefix)) t.Assert(err, c.IsNil) _, err = f.WriteString(data) t.Assert(err, c.IsNil) stat, err := f.Stat() t.Assert(err, c.IsNil) return filepath.Join(os.TempDir(), stat.Name()), nil } // flynn route add http with tls cert cert, err := tlscert.Generate([]string{"example.com"}) t.Assert(err, c.IsNil) certPath, err := writeTemp(cert.Cert, "tls-cert") t.Assert(err, c.IsNil) keyPath, err := writeTemp(cert.PrivateKey, "tls-key") certRoute := app.flynn("route", "add", "http", "--tls-cert", certPath, "--tls-key", keyPath, "example.com") t.Assert(certRoute, Succeeds) routeID = strings.TrimSpace(certRoute.Output) r, err = client.GetRoute(app.id, routeID) t.Assert(err, c.IsNil) t.Assert(r.Domain, c.Equals, "example.com") t.Assert(r.Certificate, c.NotNil) t.Assert(r.Certificate.Cert, c.Equals, strings.Trim(cert.Cert, "\n")) t.Assert(r.Certificate.Key, c.Equals, strings.Trim(cert.PrivateKey, "\n")) // flynn route update tls cert cert, err = tlscert.Generate([]string{"example.com"}) t.Assert(err, c.IsNil) certPath, err = writeTemp(cert.Cert, "tls-cert") t.Assert(err, c.IsNil) keyPath, err = writeTemp(cert.PrivateKey, "tls-key") certRoute = app.flynn("route", "update", routeID, "--tls-cert", certPath, "--tls-key", keyPath) t.Assert(certRoute, Succeeds) r, err = client.GetRoute(app.id, routeID) t.Assert(err, c.IsNil) t.Assert(r.Domain, c.Equals, "example.com") t.Assert(r.Certificate, c.NotNil) t.Assert(r.Certificate.Cert, c.Equals, strings.Trim(cert.Cert, "\n")) t.Assert(r.Certificate.Key, c.Equals, strings.Trim(cert.PrivateKey, "\n")) // flynn route remove t.Assert(app.flynn("route", "remove", routeID), Succeeds) assertRouteContains(routeID, false) }