common

package
v2.0.2+incompatible Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 7, 2018 License: Apache-2.0 Imports: 33 Imported by: 61

Documentation

Overview

Package common contains various things common to all Romana services.

Index

Constants

View Source
const (
	RoleAdmin   = "admin"
	RoleService = "service"
	RoleTenant  = "tenant"
)
View Source
const (
	CredentialUsernamePassword = "userPass"
	CredentialNone             = "none"

	UsernameKey = "ROMANA_USERNAME"
	PasswordKey = "ROMANA_PASSWORD"
)
View Source
const (
	// Flags to store.Find operation
	FindFirst      = "findFirst"
	FindLast       = "findLast"
	FindExactlyOne = "findExactlyOne"
	FindAll        = "findAll"
)
View Source
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"
	ContextKeyUser         string = "User"
	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 = ""

	// Path for authentication; if this is what is used
	// in the request we will not check the token (because
	// we are attempting to get a token at this point).
	AuthPath = "/auth"

	// Body provided.
	HookExecutableBodyArgument = "body"
)

Constants

View Source
const (
	DefaultTestConfigFile = "../common/testdata/romana.sample.yaml"
)
View Source
const (
	// DefaultTimeout, in milliseconds.
	DefaultTimeout = 500 * time.Millisecond
)
View Source
const (
	// 422 (unprocessable entity http://www.restpatterns.org/HTTP_Status_Codes/422_-_Unprocessable_Entity)
	// is not in net/http yet.
	StatusUnprocessableEntity = 422
)

Variables

View Source
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

View Source
var SupportedContentTypes = []string{"text/plain", "application/vnd.romana.v1+json", "application/vnd.romana+json", "application/json", "application/x-www-form-urlencoded"}

List of supported content types to return in a 406 response.

View Source
var SupportedContentTypesMessage = struct {
	SupportedContentTypes []string `json:"supported_content_types"`
}{
	SupportedContentTypes,
}

Above list of supported content types wrapped in a struct for converion to JSON.

Functions

func BuildInfo

func BuildInfo() string

BuildInfo return build revision and time string.

func CleanURL added in v0.9.0

func CleanURL(url string) (string, error)

CleanURL is similar to path.Clean() but to work on URLs

func Environ added in v0.8.2

func Environ() map[string]string

Environ is similar to os.Environ() but returning environment as a map instead of an array of strings.

func GetCaller added in v1.0.0

func GetCaller() string

GetCaller returns the location information of the caller of the method that invoked GetCaller.

func GetCaller2 added in v1.0.0

func GetCaller2(up int) string

GetCaller2 is similar to GetCaller but goes up the specified number of frames.

func GetMockDbName added in v1.0.0

func GetMockDbName(svc string) string

GetMockDbName creates a DB name as follows: <SERVICE_NAME>_<Result of getUniqueMockNameComponent()>

func GetPasswd added in v1.0.0

func GetPasswd() (string, error)

GetPasswd gets password from stdin.

func IPv4ToInt

func IPv4ToInt(ip net.IP) uint64

func In added in v0.9.3

func In(needle string, haystack []string) bool

In returns true if needle is found in haystack.

func InitMap added in v0.9.3

func InitMap(keyValuePairs ...KeyValue) map[string]interface{}

func IntToIPv4

func IntToIPv4(ipInt uint64) net.IP

func IsZeroValue added in v0.9.1

func IsZeroValue(val interface{}) bool

IsZeroValue checks whether the provided value is equal to the zero value for the type. Zero values would be:

  • 0 for numeric types
  • "" for strings
  • uninitialized struct for a struct
  • zero-size for a slice or a map

func MakeMultiError

func MakeMultiError(errors []error) error

MakeMultiError creates a single error object out of an array of errors as follows: 1. If the array is empty or nil, nil is returned 2. If the array has exactly 1 element, that element is returned 3. Otherwise, a MultiError is returned.

func MkMap added in v0.9.3

func MkMap() map[string]interface{}

func MkMapStr added in v0.9.3

func MkMapStr() map[string]string

func NewError

func NewError(text string, args ...interface{}) error

NewError constructs an error by formatting text with arguments.

func PressEnterToContinue

func PressEnterToContinue()

func ReadKeyFile added in v1.0.0

func ReadKeyFile(filename string) (*pem.Block, error)

ReadKeyFile reads a key from the provided file.

func String added in v0.9.0

func String(i interface{}) string

func ToBool

func ToBool(val interface{}) (bool, error)

ToBool is a convenience function that's like ParseBool but allows also "on"/"off" values.

Types

type Attribute added in v1.0.0

type Attribute struct {
	AttributeKey   string `json:"attribute_key"`
	AttributeValue string `json:"attribute_value"`
	Id             int    `sql:"AUTO_INCREMENT"`
}

An Attribute of a user is something that is used in the ABAC part of our AuthZ scheme. Not every role would be checked for atributes. For now, only if the user has a role of tenant, it's attribute for key "tenant" is checked against the tenant ID by tenant service.

type AuthMiddleware

type AuthMiddleware struct {
	PublicKey   *rsa.PublicKey
	AllowedURLs []string
}

AuthMiddleware wrapper for auth.

func NewAuthMiddleware added in v1.0.0

func NewAuthMiddleware(service Service) (AuthMiddleware, error)

NewAuthMiddleware creates new AuthMiddleware to use. Its behavior depends on whether it is for root (in which case the public key is gotten from the config file) or another service (in which case the public key is gotten from the root).

func (AuthMiddleware) Keyfunc added in v1.0.0

func (am AuthMiddleware) Keyfunc(*jwt.Token) (interface{}, error)

Keyfunc implements jwt.Keyfunc (https://godoc.org/github.com/dgrijalva/jwt-go#Keyfunc) by returning the public key

func (AuthMiddleware) ServeHTTP

func (am AuthMiddleware) ServeHTTP(writer http.ResponseWriter, request *http.Request, next http.HandlerFunc)

ServeHTTP implements the middleware contract as follows:

  1. If the path of request is one of the AllowedURLs, then this is a no-op. 2 Otherwise, checks token from request. If the token is not valid, returns a 403 FORBIDDEN status.

type AuthTokenMessage added in v1.0.0

type AuthTokenMessage struct {
	Token     string `json:"token"`
	PublicKey []byte `json:"public_key"`
}

AuthTokenMessage is returned by Root service upon a client's authentication. The token is generated by the root server depending on the information looked up on the user (roles and attributes) and the public key is the root server's public key to verify the token (which is signed by root's private key).

type AuthZChecker added in v1.0.0

type AuthZChecker func(ctx RestContext) bool

AuthZChecker takes a user and outputs whether the user is allowed to access a resource. If defined on a Route, it will be automatically invoked by wrapHandler(), which will provide RestContext.

type Config

type Config struct {
	EtcdEndpoints       []string
	EtcdPrefix          string
	InitialTopologyFile *string
	Mock                bool
}

Config is the configuration required for a Romana client library. TODO it is here temporarily until circular imports are resolved.

type Credential added in v0.8.2

type Credential struct {
	Type CredentialType

	Username string
	Password string
	// contains filtered or unexported fields
}

Container for various credentials. Currently containing Username/Password but keys, certificates, etc. can be used in the future.

func NewCredential added in v1.0.0

func NewCredential(flagSet *flag.FlagSet) *Credential

func NewCredentialCobra added in v1.0.0

func NewCredentialCobra(cmd *cli.Command) *Credential

func (*Credential) Initialize added in v1.0.0

func (c *Credential) Initialize() error

Initialize constructs appropriate Credential structure based on provided data, which includes, in the following precedence (later superseding earlier): * In case of username/password auth:

  1. As keys UsernameKey and PasswordKey in ~/.romana.yaml file
  2. As environment variables whose names are UsernameKey and PasswordKey values
  3. As --username and --password command-line flags. If --username flag is specified but --password flag is omitted, the user will be prompted for the password.

Notes:

  1. The first two precedence steps (~/.romana.yaml and environment variables) are taken care by the config module (github.com/spf13/viper)
  2. If flag.Parsed() is false at the time of this call, the command-line values are ignored.

func (*Credential) String added in v1.0.0

func (c *Credential) String() string

type CredentialType added in v0.8.2

type CredentialType string

Represents the type of credential (e.g., certificate, username-password, etc.)

type ExecErrorDetails added in v0.9.0

type ExecErrorDetails struct {
	Error string
}

type FindFlag added in v0.9.1

type FindFlag string

type HttpError

type HttpError struct {
	// HTTP status code
	StatusCode int         `json:"status_code"`
	Details    interface{} `json:"details,omitempty"`
	// ResourceID specifies the relevant resource ID, if applicable
	ResourceID string `json:"resource_id,omitempty"`
	// ResourceType specifies the relevant resource type, if applicable
	ResourceType string `json:"resource_type,omitempty"`
	SeeAlso      string `json:"see_also, omitempty"`
}

HttpError is a structure that represents, well, an HTTP error.

func NewError400

func NewError400(details interface{}) HttpError

NewError400 creates an HttpError with 400 (http.StatusBadRequest) status code.

func NewError403 added in v1.0.0

func NewError403() HttpError

NewError403 creates a 403 FORBIDDEN message.

func NewError404

func NewError404(resourceType string, resourceID string) HttpError

NewError404 creates a 404 NOT FOUND message.

func NewError500

func NewError500(details interface{}) HttpError

NewError500 creates an HttpError with 500 (http.StatusInternalServerError) status code.

func NewErrorConflict added in v0.9.0

func NewErrorConflict(details interface{}) HttpError

NewErrorConflict creates an HttpError with 409 (http.StatusConflict) status code.

func NewHttpError added in v0.9.0

func NewHttpError(code int, details interface{}) HttpError

NewError helps to construct new Error structure.

func NewUnprocessableEntityError added in v0.9.0

func NewUnprocessableEntityError(details interface{}) HttpError

NewUnprocessableEntityError creates an HttpError with 423 (StatusUnprocessableEntity) status code.

func (HttpError) Error

func (httpErr HttpError) Error() string

String returns formatted HTTP error for human consumption.

func (HttpError) StatusText

func (err HttpError) StatusText() string

StatusText returns the string value of the HttpError corresponding to the StatusCode.

type IP

type IP struct {
	// contains filtered or unexported fields
}

func MakeIPv4

func MakeIPv4(a, b, c, d byte) IP

type KeyValue added in v0.9.3

type KeyValue struct {
	Key   string
	Value interface{}
}

KeyValue represents a key-value pair (similar to Java's Map.Entry)

func KV added in v0.9.3

func KV(key string, value interface{}) KeyValue

KV is a convenience function to create a KeyValue value.

type LinkResponse

type LinkResponse struct {
	Href string `json:"href,omitempty"`
	Rel  string `json:"rel,omitempty"`
}

LinkResponse structure represents the commonly occurring

{
       "href" : "https://<own-addr>",
       "rel"  : "self"
 }

part of the response.

type Links []LinkResponse

func (Links) FindByRel

func (links Links) FindByRel(rel string) string

FindByRel finds the path (href) for a link based on its rel value. This is because in the REST message links are organized as an array of structures containing href and rel, but, of course, in actual usage it is easier to be used as a map.

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 is a facility to collect multiple number of errors but present them as a single error interface. For example, 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 NewMultiError

func NewMultiError() *MultiError

NewMultiError creates a new MultiError object to which errors can be added.

func (MultiError) Add

func (me MultiError) Add(err error)

Add adds an error to the MultiError object.

func (*MultiError) Error

func (m *MultiError) Error() string

Error satisfies Error method on error interface and returns a concatenated string of all error messages.

func (*MultiError) GetError

func (m *MultiError) GetError() error

GetError returns nil if there are no underlying errors, the single error if there is only one, and the MultiError object if there is more than one.

func (*MultiError) GetErrors added in v0.9.0

func (m *MultiError) GetErrors() []error

GetErrors returns all errors in this MultiError object.

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 PortUpdateMessage

type PortUpdateMessage struct {
	Port uint64 `json:"port"`
}

Message to register with the root service the actual port a service is listening on.

type Raw added in v0.9.0

type Raw struct {
	Body string
}

Raw is a type that can be returned from any service's route and the middleware will not try to marshal it.

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
	User         User
	// Output of the hook if any run before the execution of the handler.
	HookOutput 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 (as host:port)
	Address string
	// Channel to communicate with the service
	Channel chan ServiceMessage
}

RestServiceInfo describes information about a running Romana service.

func InitializeService

func InitializeService(service Service, config Config) (*RestServiceInfo, error)

InitializeService initializes the service with the provided config and starts it. The channel returned allows the caller 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

func RunNegroni(n *negroni.Negroni, addr string) (*RestServiceInfo, error)

RunNegroni is a convenience function that runs the negroni stack as a provided HTTP server, with the following caveats:

  1. the Handler field of the provided serverConfig should be nil, because the Handler used will be the n Negroni object.

type Role added in v0.8.2

type Role struct {
	Name string `json:"name"`
	Id   int    `sql:"AUTO_INCREMENT"`
}

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 RomanaTestSuite added in v1.0.0

type RomanaTestSuite struct {
	// contains filtered or unexported fields
}

RomanaTestSuite holds state for use in testing.

func (*RomanaTestSuite) CleanUp added in v1.0.0

func (rts *RomanaTestSuite) CleanUp()

func (*RomanaTestSuite) GetMockSqliteFile added in v1.0.0

func (rts *RomanaTestSuite) GetMockSqliteFile(svc string) string

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

	AuthZChecker AuthZChecker
}

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 Routes

type Routes []Route

Routes provided by each service.

type Service

type Service interface {
	Initialize(clientConfig Config) error

	// Returns the routes that this service works with
	Routes() Routes

	// Name returns the name of this service.
	Name() string

	// GetAddr returns the host/port the service is listening on.
	GetAddress() string
}

Service is the interface that services implement.

type ServiceMessage

type ServiceMessage string

Type definitions

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 (s ServiceUtils) AddStatus(requestId string, value interface{})

AddStatus adds a status of a request

func (ServiceUtils) GetStatus

func (s ServiceUtils) GetStatus(resourceType string, requestId string) (interface{}, error)

GetStatus gets the status of the request or returns an common.HttpError (404) if not found.

type UnmarshallerMiddleware

type UnmarshallerMiddleware struct {
}

func NewUnmarshaller

func NewUnmarshaller() *UnmarshallerMiddleware

func (UnmarshallerMiddleware) ServeHTTP

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.

type User added in v1.0.0

type User struct {
	UserId             int `sql:"AUTO_INCREMENT" json:"user_id" gorm:"primary_key"`
	jwt.StandardClaims `json:"claims"`
	Username           string      `json:"username,omitempty"`
	Password           string      `json:"password,omitempty"`
	Roles              []Role      `gorm:"many2many:user_roles;ForeignKey:user_id"`
	Attributes         []Attribute `gorm:"many2many:user_attributes;ForeignKey:user_id"`
}

User has multiple roles and multiple attributes.

var DefaultAdminUser User

DefaultAdminUser is a dummy user having admin role. It is used when authentication is off.

Directories

Path Synopsis
api
log

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL