Documentation ¶
Overview ¶
Package common authentication related code.
Package common build information support.
This file contains the implementation of HttpClient and related utilities.
Package common contains various things common to all Romana services.
Package common contains things related to the REST framework.
Contains general routines and definitions for a generic back-end storage (currently geared towards RDBMS but not necessarily limited to that).
Index ¶
- Constants
- Variables
- func BuildInfo() string
- func IPv4ToInt(ip net.IP) uint64
- func IntToIPv4(ipInt uint64) net.IP
- func MakeMultiError(errors []error) error
- func MockPortsInConfig(fname string) error
- func PressEnterToContinue()
- func ToBool(val string) (bool, error)
- func WriteConfig(config Config, fname string) error
- type Api
- type AuthBackend
- type AuthMiddleware
- type Authenticator
- type CommonConfig
- type Config
- type Datacenter
- type DbStore
- type HostMessage
- type HttpError
- type IP
- type IndexResponse
- type LinkResponse
- type Links
- type MakeMessage
- type Marshaller
- type MultiError
- type NegotiatorMiddleware
- type PlaceholderAuth
- type PortUpdateMessage
- type Principal
- type RestClient
- func (rc *RestClient) Get(url string, result interface{}) error
- func (rc *RestClient) GetServiceConfig(rootServiceUrl string, svc Service) (*ServiceConfig, error)
- func (rc *RestClient) GetServiceUrl(rootServiceUrl string, name string) (string, error)
- func (rc *RestClient) NewUrl(dest string) error
- func (rc *RestClient) Post(url string, data interface{}, result interface{}) error
- type RestClientConfig
- type RestContext
- type RestHandler
- type RestServiceInfo
- type RomanaHandler
- type RootIndexResponse
- type Route
- type Routes
- type Service
- type ServiceConfig
- type ServiceMessage
- type ServiceResponse
- type ServiceStore
- type ServiceUtils
- type Store
- type StoreConfig
- type UnmarshallerMiddleware
- type UnwrappedRestHandlerInput
Constants ¶
const ( // For passing in Gorilla Mux context the unmarshalled data ContextKeyUnmarshalledMap string = "UnmarshalledMap" // For passing in Gorilla Mux context path variables ContextKeyQueryVariables string = "QueryVars" // For passing in Gorilla Mux context the original body data ContextKeyOriginalBody string = "OriginalBody" ContextKeyMarshaller string = "Marshaller" // DefaultRestTimeout, in milliseconds. DefaultRestTimeout = 500 DefaultRestRetries = 3 ReadWriteTimeoutDelta = 10 // Name of the query parameter used for request token RequestTokenQueryParameter = "RequestToken" HeaderContentType = "content-type" Starting ServiceMessage = "Starting." // JSON TimeoutMessage = "{ \"error\" : \"Timed out\" }" // Empty string returned when there is a string return // but there is an error so no point in returning any // value. ErrorNoValue = "" )
Constants
Variables ¶
var ContentTypeMarshallers map[string]Marshaller = map[string]Marshaller{
"": jsonMarshaller{},
"application/json": jsonMarshaller{},
"application/vnd.romana.v1+json": jsonMarshaller{},
"application/vnd.romana+json": jsonMarshaller{},
"application/x-www-form-urlencoded": formMarshaller{},
}
ContentTypeMarshallers maps MIME type to Marshaller instances
Functions ¶
func MakeMultiError ¶
MakeMultiError creates a single MultiError (or nil!) out of an array of error objects.
func MockPortsInConfig ¶
MockPortsInConfig will take the config file specified and replace the ports with 0 to use arbitrary ports and write it out to /tmp/romana.yaml
func PressEnterToContinue ¶
func PressEnterToContinue()
func ToBool ¶
toBool is a convenience function that's like ParseBool but allows also "on"/"off" values.
func WriteConfig ¶
WriteConfig writes config from file to structure
Types ¶
type Api ¶
type Api struct { // Host to listen on. Host string `yaml:"host" json:"host"` // Port to listen on. Port uint64 `yaml:"port" json:"port"` // Root service URL RootServiceUrl string `json:"root_service_url,omitempty" yaml:"root_service_url,omitempty"` // Rest timeout in milliseconds (if omitted, defaults to DefaultRestTimeout) RestTimeoutMillis int64 `yaml:"rest_timeout_millis,omitempty" json:"rest_timeout_millis,omitempty"` RestRetries int `yaml:"rest_retries,omitempty" json:"rest_retries,omitempty"` RestTestMode bool `yaml:"rest_test_mode,omitempty" json:"rest_test_mode,omitempty"` }
Api part of service configuration (host/port).
func (Api) GetHostPort ¶
type AuthMiddleware ¶
type AuthMiddleware struct {
Authenticator Authenticator
}
AuthMiddleware wrapper for auth.
func (AuthMiddleware) ServeHTTP ¶
func (am AuthMiddleware) ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc)
type Authenticator ¶
type Authenticator interface { // As this is a placeholder, we are not dealing with // details yet, tokens vs credentials, principals vs roles, etc. Authenticate() Principal }
Authenticator is the interface that will be used by AuthMiddleware to provide authentication. Details to be worked out later.
type CommonConfig ¶
type CommonConfig struct {
Api *Api `yaml:"api" json:"api"`
}
CommonConfig stores configuration that is common to all services. For things such as API information (host/port), DB, etc.
type Config ¶
type Config struct {
Services map[string]ServiceConfig
}
Config provides the main configuration object
func ReadConfig ¶
ReadConfig parses the configuration file provided and returns ReadConfig reads config from file to structure
type Datacenter ¶
type Datacenter struct { Id uint64 `sql:"AUTO_INCREMENT"` IpVersion uint `json:"ip_version"` // We don't need to store this, but calculate and pass around Prefix uint64 `json:"prefix"` Cidr string PrefixBits uint `json:"prefix_bits"` PortBits uint `json:"port_bits"` TenantBits uint `json:"tenant_bits"` SegmentBits uint `json:"segment_bits"` // We don't need to store this, but calculate and pass around EndpointBits uint `json:"endpoint_bits"` EndpointSpaceBits uint `json:"endpoint_space_bits"` Name string `json:"name"` }
Datacenter represents the configuration of a datacenter
type DbStore ¶
type DbStore struct { ServiceStore ServiceStore Config *StoreConfig Db *gorm.DB // contains filtered or unexported fields }
DbStore is a structure storing information specific to RDBMS-based implementation of Store.
func (*DbStore) Connect ¶
Connect connects to the appropriate DB (mutating dbStore's state with the connection information), or returns an error.
func (*DbStore) CreateSchema ¶
CreateSchema creates the schema in this DB. If force flag is specified, the schema is dropped and recreated.
func (*DbStore) GetPasswordFunction ¶
GetPasswordFunction returns appropriate function to hash password depending on the underlying DB (note that in sqlite it is plain text).
type HostMessage ¶
type HostMessage struct { Id string `json:"id"` Name string `json:"name"` Ip string `json:"ip"` RomanaIp string `json:"romana_ip"` AgentPort int `json:"agent_port"` Links Links `json:"links"` }
HostMessage is a structure representing information about the host for the purposes of REST communications
type HttpError ¶
type HttpError struct { StatusCode int `json:"status_code"` StatusText string `json:"status_text"` Message string `json:"message"` }
HttpError is a structure that represents, well, an Http error.
func NewError400 ¶
func NewError404 ¶
NewError404 creates a 404 NOT FOUND message.
func NewError500 ¶
type IndexResponse ¶
Response to /
type LinkResponse ¶
LinkResponse structure represents the commonly occurring
{ "href" : "https://<own-addr>", "rel" : "self" }
part of the response.
type Links ¶
type Links []LinkResponse
type MakeMessage ¶
type MakeMessage func() interface{}
MakeMessage is a factory function, which should return a pointer to an instance into which we will unmarshal wire data.
type Marshaller ¶
type Marshaller interface { Marshal(v interface{}) ([]byte, error) Unmarshal(data []byte, v interface{}) error }
Marshaller is capable of marshalling and unmarshalling data to/from the wire.
type MultiError ¶
type MultiError struct {
// contains filtered or unexported fields
}
MultiError adapts GORM (ORM - see https://github.com/jinzhu/gorm) array of errors found in GetErrors() to a single error interface. GORM does not return errors at every turn. It accumulates them and returns them whenever you feel like calling GetErrors() (https://godoc.org/github.com/jinzhu/gorm#DB.GetErrors). Since this is not consistent with the rest of the code, I prefer to isolate it here and make an adapter.
func (*MultiError) Error ¶
func (m *MultiError) Error() string
Error satisfies Error method on error interface and returns a concatenated string of all error messages.
type NegotiatorMiddleware ¶
type NegotiatorMiddleware struct { }
func NewNegotiator ¶
func NewNegotiator() *NegotiatorMiddleware
func (NegotiatorMiddleware) ServeHTTP ¶
func (negotiator NegotiatorMiddleware) ServeHTTP(writer http.ResponseWriter, request *http.Request, next http.HandlerFunc)
type PlaceholderAuth ¶
type PlaceholderAuth struct { }
func (PlaceholderAuth) Authenticate ¶
func (p PlaceholderAuth) Authenticate() Principal
type PortUpdateMessage ¶
type PortUpdateMessage struct {
Port uint64 `json:"port"`
}
Message to register with the root service the actual port a service is listening on.
type Principal ¶
Principal is a placeholder for a Principal structure for authentication. We'll leave roles and other stuff for later.
type RestClient ¶
type RestClient struct {
// contains filtered or unexported fields
}
Rest Client for the Romana services. Incorporates facilities to deal with various REST requests.
func NewRestClient ¶
func NewRestClient(url string, config RestClientConfig) (*RestClient, error)
NewRestClient creates a new Rest client.
func (*RestClient) Get ¶
func (rc *RestClient) Get(url string, result interface{}) error
Get applies GET method to the specified URL, putting the result into the provided interface
func (*RestClient) GetServiceConfig ¶
func (rc *RestClient) GetServiceConfig(rootServiceUrl string, svc Service) (*ServiceConfig, error)
GetServiceConfig retrieves configuration for a given service from the root service.
func (*RestClient) GetServiceUrl ¶
func (rc *RestClient) GetServiceUrl(rootServiceUrl string, name string) (string, error)
GetServiceUrl is a convenience function, which, given the root service URL and name of desired service, returns the URL of that service.
func (*RestClient) NewUrl ¶
func (rc *RestClient) NewUrl(dest string) error
NewUrl sets the client's new URL (yes, it mutates) to dest. If dest is a relative URL then it will be based on the previous value of the URL that the RestClient had.
func (*RestClient) Post ¶
func (rc *RestClient) Post(url string, data interface{}, result interface{}) error
Post applies POST method to the specified URL
type RestClientConfig ¶
RestClientConfig holds configuration for restful client.
func GetDefaultRestClientConfig ¶
func GetDefaultRestClientConfig() RestClientConfig
func GetRestClientConfig ¶
func GetRestClientConfig(config ServiceConfig) RestClientConfig
GetRestClientConfig returns a RestClientConfig based on a ServiceConfig
type RestContext ¶
type RestContext struct { // Path variables as described in https://godoc.org/code.google.com/p/gorilla/mux PathVariables map[string]string // QueryVariables stores key-value-list map of query variables, see url.Values // for more details. QueryVariables url.Values // Unique identifier for a request. RequestToken string }
RestContext contains the context of the REST request other than the body data that has been unmarshaled.
type RestHandler ¶
type RestHandler func(input interface{}, context RestContext) (interface{}, error)
RestHandler specifies type of a function that each Route provides. It takes (for now) an interface as input, and returns any interface. The middleware provided in this file takes care of unmarshalling the data from the wire to the input object (the type of the object created will be determined by the type of the instance provided in Consumes field of Route type, below), and of marshalling the returned object to the wire (the type of which is determined by type of the instance provided in Produces field of Route type, below).
type RestServiceInfo ¶
type RestServiceInfo struct { // Address being listened on Address string // Channel to communicate with the service Channel chan ServiceMessage }
func InitializeService ¶
func InitializeService(service Service, config ServiceConfig) (*RestServiceInfo, error)
InitializeService initializes the service with the provided config and starts it. The channel returned allows the calller to wait for a message from the running service. Messages are of type ServiceMessage above. It can be used for launching service from tests, etc.
func ListenAndServe ¶
func ListenAndServe(svr *http.Server) (*RestServiceInfo, error)
ListenAndServe is same as http.ListenAndServe except it returns the address that will be listened on (which is useful when using arbitrary ports). See https://github.com/golang/go/blob/master/src/net/http/server.go
func RunNegroni ¶
RunNegroni is a convenience function that runs the negroni stack as a provided HTTP server, with the following caveats:
- the Handler field of the provided serverConfig should be nil, because the Handler used will be the n Negroni object.
type RomanaHandler ¶
type RomanaHandler struct {
// contains filtered or unexported fields
}
RomanaHandler interface to comply with http.Handler
func (RomanaHandler) ServeHTTP ¶
func (romanaHandler RomanaHandler) ServeHTTP(writer http.ResponseWriter, request *http.Request)
ServeHTTP is required by https://golang.org/pkg/net/http/#Handler
type RootIndexResponse ¶
type RootIndexResponse struct { ServiceName string `json:"serviceName"` Links Links Services []ServiceResponse }
RootIndexResponse represents a response from the / path specific for root service only.
type Route ¶
type Route struct { // REST method Method string // Pattern (see http://www.gorillatoolkit.org/pkg/mux) Pattern string // Handler (see documentation above) Handler RestHandler // This should return a POINTER to an instance which // this route expects as an input. MakeMessage MakeMessage // Whether this route is using a request token. If true, the // request token will be parsed out of the request and made // available in RestContext. It can then // used by the handler to achieve idempotence. UseRequestToken bool }
Route determines an action taken on a URL pattern/HTTP method. Each service can define a route See routes.go and handlers.go in root package for a demonstration of use
type Service ¶
type Service interface { // SetConfig sets the configuration, validating it if needed // and returning an error if not valid. SetConfig(config ServiceConfig) error // Initializes the service (mostly for error reporting, could be a no-op) Initialize() error // Returns the routes that this service works with Routes() Routes // Name returns the name of this service. Name() string }
Service is the interface that microservices implement.
type ServiceConfig ¶
type ServiceConfig struct { Common CommonConfig `json:"common" yaml:"common"` // TODO I really dislike this name, but there // should be some common part that's applicable // to all services, and something service-specific // that we in common do not need to know about. ServiceSpecific map[string]interface{} `json:"config" yaml:"config,omitempty"` }
ServiceConfig contains common configuration for each service and also a section for service-specific configuration. This may be an overkill but if we have a type system, we should use it instead of just dictionaries.
type ServiceStore ¶
type ServiceStore interface { // Entities returns list of entities (DB tables) this store is managing. Entities() []interface{} // CreateSchemaPostProcess runs whatever required post-processing after // schema creation (perhaps initializing DB with some initial or sample data). CreateSchemaPostProcess() error }
ServiceStore interface is what each service's store needs to implement.
type ServiceUtils ¶
type ServiceUtils struct { // ResourceIdToStatus is a maps request ID // to status. A request ID can be a RequestToken if required, // or a resource ID. In general the idea is that this is used // in conjunction with RequestToken. // See also // - Route.UseRequestToken // - RestContext.RequestToken RequestIdToStatus map[string]interface{} // RequestIdToTimestamp maps request ID (for more information // on what that is see RequestIdToStatus) to the timestamp // of the original request. It will later be used for things // such as possible expiration, etc., but for now it's just a // placeholder. RequestIdToTimestamp map[string]int64 }
ServiceUtils represents functionality common to various services. One example of such functionality is asynchronous processing -- a service can accept a request for creation of an object and return a 202 ACCEPTED, creating an entry that can be queried for status.
func (ServiceUtils) AddStatus ¶
func (su ServiceUtils) AddStatus(requestId string, value interface{})
AddStatus adds a status of a request
type Store ¶
type Store interface { // SetConfig sets the configuration SetConfig(configMap map[string]interface{}) error // Connect connects to the store Connect() error // Create the schema, dropping existing one if the force flag is specified CreateSchema(force bool) error }
Store defines generic store interface that can be used by any service for persistence.
type StoreConfig ¶
type StoreConfig struct { Host string Port uint64 Username string Password string Database string // Database type, e.g., sqlite3, mysql, etc. // TODO add a set of constants for it. Type string }
StoreConfig stores information needed for a DB connection.
type UnmarshallerMiddleware ¶
type UnmarshallerMiddleware struct { }
func NewUnmarshaller ¶
func NewUnmarshaller() *UnmarshallerMiddleware
func (UnmarshallerMiddleware) ServeHTTP ¶
func (m UnmarshallerMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)
Unmarshals request body if needed. If not acceptable, returns an http.StatusNotAcceptable and this ends this request's lifecycle.
type UnwrappedRestHandlerInput ¶
type UnwrappedRestHandlerInput struct { ResponseWriter http.ResponseWriter Request *http.Request }
UnwrappedRestHandlerInput is used to pass in http.Request and http.ResponseWriter, should some service like unfettered access directly to them. In such a case, the service's RestHandler's input will be of this type; and the return value will be ignored.