2018-12-03 10:32:05 +00:00
package rest
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
2019-08-03 01:58:23 +00:00
"github.com/containous/traefik/v2/pkg/config/dynamic"
"github.com/containous/traefik/v2/pkg/log"
"github.com/containous/traefik/v2/pkg/provider"
"github.com/containous/traefik/v2/pkg/safe"
"github.com/gorilla/mux"
2018-12-03 10:32:05 +00:00
"github.com/unrolled/render"
)
var _ provider . Provider = ( * Provider ) ( nil )
// Provider is a provider.Provider implementation that provides a Rest API.
type Provider struct {
2019-09-06 13:08:04 +00:00
Insecure bool ` description:"Activate REST Provider directly on the entryPoint named traefik." json:"insecure,omitempty" toml:"insecure,omitempty" yaml:"insecure,omitempty" export:"true" `
2019-07-10 07:26:04 +00:00
configurationChan chan <- dynamic . Message
2019-06-17 09:48:05 +00:00
}
// SetDefaults sets the default values.
func ( p * Provider ) SetDefaults ( ) {
2018-12-03 10:32:05 +00:00
}
var templatesRenderer = render . New ( render . Options { Directory : "nowhere" } )
// Init the provider.
func ( p * Provider ) Init ( ) error {
return nil
}
2019-09-06 13:08:04 +00:00
// Handler creates an http.Handler for the Rest API
func ( p * Provider ) Handler ( ) http . Handler {
router := mux . NewRouter ( )
p . Append ( router )
return router
}
2018-12-03 10:32:05 +00:00
// Append add rest provider routes on a router.
func ( p * Provider ) Append ( systemRouter * mux . Router ) {
systemRouter .
Methods ( http . MethodPut ) .
Path ( "/api/providers/{provider}" ) .
HandlerFunc ( func ( response http . ResponseWriter , request * http . Request ) {
vars := mux . Vars ( request )
if vars [ "provider" ] != "rest" {
response . WriteHeader ( http . StatusBadRequest )
fmt . Fprint ( response , "Only 'rest' provider can be updated through the REST API" )
return
}
2019-07-12 23:24:03 +00:00
configuration := new ( dynamic . Configuration )
2018-12-03 10:32:05 +00:00
body , _ := ioutil . ReadAll ( request . Body )
2019-02-05 16:10:03 +00:00
if err := json . Unmarshal ( body , configuration ) ; err != nil {
2018-12-03 10:32:05 +00:00
log . WithoutContext ( ) . Errorf ( "Error parsing configuration %+v" , err )
http . Error ( response , fmt . Sprintf ( "%+v" , err ) , http . StatusBadRequest )
2019-02-05 16:10:03 +00:00
return
}
2019-07-12 23:24:03 +00:00
p . configurationChan <- dynamic . Message { ProviderName : "rest" , Configuration : configuration }
2019-02-05 16:10:03 +00:00
if err := templatesRenderer . JSON ( response , http . StatusOK , configuration ) ; err != nil {
log . WithoutContext ( ) . Error ( err )
2018-12-03 10:32:05 +00:00
}
} )
}
// Provide allows the provider to provide configurations to traefik
// using the given configuration channel.
2019-07-10 07:26:04 +00:00
func ( p * Provider ) Provide ( configurationChan chan <- dynamic . Message , pool * safe . Pool ) error {
2018-12-03 10:32:05 +00:00
p . configurationChan = configurationChan
return nil
}