diff --git a/api/models/route.go b/api/models/route.go index 9ab6c3eff..c21642990 100644 --- a/api/models/route.go +++ b/api/models/route.go @@ -15,15 +15,16 @@ const ( ) var ( + ErrInvalidPayload = errors.New("Invalid payload") + ErrRoutesAlreadyExists = errors.New("Route already exists") ErrRoutesCreate = errors.New("Could not create route") - ErrRoutesUpdate = errors.New("Could not update route") - ErrRoutesRemoving = errors.New("Could not remove route from datastore") ErrRoutesGet = errors.New("Could not get route from datastore") ErrRoutesList = errors.New("Could not list routes from datastore") - ErrRoutesAlreadyExists = errors.New("Route already exists") - ErrRoutesNotFound = errors.New("Route not found") ErrRoutesMissingNew = errors.New("Missing new route") - ErrInvalidPayload = errors.New("Invalid payload") + ErrRoutesNotFound = errors.New("Route not found") + ErrRoutesPathImmutable = errors.New("Could not update route - path is immutable") + ErrRoutesRemoving = errors.New("Could not remove route from datastore") + ErrRoutesUpdate = errors.New("Could not update route") ) type Routes []*Route diff --git a/api/server/routes_test.go b/api/server/routes_test.go index a03e4a6a1..672fcd35c 100644 --- a/api/server/routes_test.go +++ b/api/server/routes_test.go @@ -203,7 +203,17 @@ func TestRouteUpdate(t *testing.T) { Path: "/myroute/do", }, }, - }, "/v1/apps/a/routes/myroute/do", `{ "route": { "image": "iron/hello", "path": "/myroute" } }`, http.StatusOK, nil}, + }, "/v1/apps/a/routes/myroute/do", `{ "route": { "image": "iron/hello" } }`, http.StatusOK, nil}, + + // Addresses #381 + {&datastore.Mock{ + Routes: []*models.Route{ + { + AppName: "a", + Path: "/myroute/do", + }, + }, + }, "/v1/apps/a/routes/myroute/do", `{ "route": { "path": "/otherpath" } }`, http.StatusForbidden, nil}, } { rnr, cancel := testRunner(t) router := testRouter(test.ds, &mqs.Mock{}, rnr, tasks) diff --git a/api/server/routes_update.go b/api/server/routes_update.go index 108404a3b..563b154a3 100644 --- a/api/server/routes_update.go +++ b/api/server/routes_update.go @@ -30,6 +30,12 @@ func handleRouteUpdate(c *gin.Context) { return } + if wroute.Route.Path != "" { + log.Debug(models.ErrRoutesPathImmutable) + c.JSON(http.StatusForbidden, simpleError(models.ErrRoutesPathImmutable)) + return + } + wroute.Route.AppName = c.Param("app") wroute.Route.Path = path.Clean(c.Param("route")) diff --git a/docs/routes.md b/docs/routes.md new file mode 100644 index 000000000..5ba7e619e --- /dev/null +++ b/docs/routes.md @@ -0,0 +1,21 @@ +# Routes + +Each application has several functions represented through routes. + +## Route level configuration + +When creating or updating an app, you can pass in a map of config variables. + +`config` is a map of values passed to the route runtime in the form of +environment variables. + +Note: Route level configuration overrides app level configuration. + +```sh +fn routes create --config k1=v1 --config k2=v2 myapp /path image +``` + +## Notes + +Route paths are immutable. If you need to change them, the appropriate approach +is to add a new route with the modified path. \ No newline at end of file diff --git a/docs/swagger.yml b/docs/swagger.yml index 4eb488a71..460f161dd 100644 --- a/docs/swagger.yml +++ b/docs/swagger.yml @@ -322,6 +322,7 @@ definitions: path: type: string description: URL path that will be matched to this route + readOnly: true image: description: Name of Docker image to use in this route. You should include the image tag, which should be a version number, to be more accurate. Can be overridden on a per route basis with route.image. type: string