2018-12-03 11:32:05 +01:00
package rest
import (
"encoding/json"
"fmt"
"net/http"
2019-08-03 03:58:23 +02:00
"github.com/gorilla/mux"
2022-11-21 18:36:05 +01:00
"github.com/rs/zerolog/log"
2023-02-03 15:24:05 +01:00
"github.com/traefik/traefik/v3/pkg/config/dynamic"
"github.com/traefik/traefik/v3/pkg/provider"
"github.com/traefik/traefik/v3/pkg/safe"
2018-12-03 11:32:05 +01: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 15:08:04 +02: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 09:26:04 +02:00
configurationChan chan <- dynamic . Message
2019-06-17 11:48:05 +02:00
}
// SetDefaults sets the default values.
2019-11-14 16:40:05 +01:00
func ( p * Provider ) SetDefaults ( ) { }
2018-12-03 11:32:05 +01:00
var templatesRenderer = render . New ( render . Options { Directory : "nowhere" } )
// Init the provider.
func ( p * Provider ) Init ( ) error {
return nil
}
2020-05-11 12:06:07 +02:00
// CreateRouter creates a router for the Rest API.
2019-11-14 16:40:05 +01:00
func ( p * Provider ) CreateRouter ( ) * mux . Router {
2019-09-06 15:08:04 +02:00
router := mux . NewRouter ( )
2019-11-14 16:40:05 +01:00
router . Methods ( http . MethodPut ) . Path ( "/api/providers/{provider}" ) . Handler ( p )
2019-09-06 15:08:04 +02:00
return router
}
2019-11-14 16:40:05 +01:00
func ( p * Provider ) ServeHTTP ( rw http . ResponseWriter , req * http . Request ) {
vars := mux . Vars ( req )
if vars [ "provider" ] != "rest" {
http . Error ( rw , "Only 'rest' provider can be updated through the REST API" , http . StatusBadRequest )
return
}
2018-12-03 11:32:05 +01:00
2019-11-14 16:40:05 +01:00
configuration := new ( dynamic . Configuration )
2019-02-05 17:10:03 +01:00
2019-11-14 16:40:05 +01:00
if err := json . NewDecoder ( req . Body ) . Decode ( configuration ) ; err != nil {
2022-11-21 18:36:05 +01:00
log . Error ( ) . Err ( err ) . Msg ( "Error parsing configuration" )
2019-11-14 16:40:05 +01:00
http . Error ( rw , fmt . Sprintf ( "%+v" , err ) , http . StatusBadRequest )
return
}
2019-02-05 17:10:03 +01:00
2019-11-14 16:40:05 +01:00
p . configurationChan <- dynamic . Message { ProviderName : "rest" , Configuration : configuration }
if err := templatesRenderer . JSON ( rw , http . StatusOK , configuration ) ; err != nil {
2022-11-21 18:36:05 +01:00
log . Error ( ) . Err ( err ) . Send ( )
2019-11-14 16:40:05 +01:00
}
2018-12-03 11:32:05 +01:00
}
// Provide allows the provider to provide configurations to traefik
// using the given configuration channel.
2019-07-10 09:26:04 +02:00
func ( p * Provider ) Provide ( configurationChan chan <- dynamic . Message , pool * safe . Pool ) error {
2018-12-03 11:32:05 +01:00
p . configurationChan = configurationChan
return nil
}