echosight

package
v0.0.0-...-0b10b3f Latest Latest
Warning

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

Go to latest
Published: May 1, 2024 License: MIT Imports: 22 Imported by: 0

Documentation

Overview

Source: https://github.com/benbjohnson/wtf/blob/main/error.go

Index

Constants

View Source
const (
	ECONFLICT       string = "conflict"
	EINTERNAL       string = "internal"
	EINVALID        string = "invalid"
	ENOTFOUND       string = "not_found"
	ENOTIMPLEMENTED string = "not_implemented"
	EUNAUTHORIZED   string = "unauthorized"
)

Application error codes.

View Source
const (
	AdminUserID string = "00000000-0000-0000-0000-000000000001"
)
View Source
const (
	EventCheckResult = "check_result"
)
View Source
const (
	UserSessionKey string = "userID"
)

Variables

View Source
var (
	Name     string = "EchoSight"
	Version  string = "undefined"
	Revision string = "undefined"
)

Build version & commit SHA.

View Source
var AnonymusUser = &User{}
View Source
var (
	// PrefSafelist list of valid preference names
	PrefSafelist = []string{
		"smtp_host",
		"smtp_port",
		"smtp_user",
		"smtp_sender",
		"smtp_password",
		"smtp_password_crypt",
		"smtp_enabled",
		"telegram_bot_token",
		"telegram_chat_ids",
		"telegram_enabled",
	}
)

Functions

func CorrelationIDFromContext

func CorrelationIDFromContext(ctx context.Context) string

func ErrorCode

func ErrorCode(err error) string

ErrorCode unwraps an application error and returns its code. Non-application errors always return EINTERNAL.

func ErrorMessage

func ErrorMessage(err error) string

ErrorMessage unwraps an application error and returns its message. Non-application errors always return "Internal error".

func NewContextWithCorrelationID

func NewContextWithCorrelationID(ctx context.Context, id string) context.Context

func NewContextWithUser

func NewContextWithUser(ctx context.Context, user *User) context.Context

NewContextWithUser returns a new context with the given user.

func UserIDFromContext

func UserIDFromContext(ctx context.Context) uuid.UUID

UserIDFromContext is a helper function that returns the ID of the current logged in user. Returns an empty string if no user is logged in.

func ValidateDetector

func ValidateDetector(v *validator.Validator, detector *Detector)

func ValidateDetectorConfig

func ValidateDetectorConfig(d *Detector) bool

func ValidateEmail

func ValidateEmail(v *validator.Validator, email string)

func ValidateHost

func ValidateHost(v *validator.Validator, host *Host)

func ValidateTokenPlainText

func ValidateTokenPlainText(v *validator.Validator, tokenPlaintext string)

Types

type AddressType

type AddressType string
const (
	AddressTypeIPv4 AddressType = "IPv4"
	AddressTypeIPv6 AddressType = "IPv6"
)

func (AddressType) String

func (at AddressType) String() string

type AgentConfig

type AgentConfig struct {
	IP      string        `json:"ip"`
	Command agent.Command `json:"command"`
	Count   int           `json:"count,omitempty"`

	WarnThreshold     float64 `json:"warnThreshold"`
	CriticalThreshold float64 `json:"criticalThreshold"`
	// contains filtered or unexported fields
}

func (*AgentConfig) Check

func (a *AgentConfig) Check(ctx context.Context) *Result

func (*AgentConfig) Detector

func (a *AgentConfig) Detector() *Detector

func (*AgentConfig) ID

func (a *AgentConfig) ID() string

func (*AgentConfig) Interval

func (a *AgentConfig) Interval() time.Duration

func (*AgentConfig) Validate

func (a *AgentConfig) Validate() bool

type AppPermission

type AppPermission string
const (
	PermissionCreateHosts    AppPermission = "create_hosts"
	PermissionCreateServices AppPermission = "create_services"
)

type Cache

type Cache interface {
	Get(ctx context.Context, namespace string, id string) ([]byte, error)
	Put(ctx context.Context, namespace string, id string, data []byte, duration time.Duration) error
	Update(ctx context.Context, namespace string, id string, data []byte, duration time.Duration) error
	Delete(ctx context.Context, namespace string, id string) error
}

type CheckHistory

type CheckHistory struct {
	Results []*Result
}

func (*CheckHistory) AddResult

func (ch *CheckHistory) AddResult(result *Result)

func (*CheckHistory) StateChanged

func (ch *CheckHistory) StateChanged() bool

func (*CheckHistory) WarnOrCritical

func (ch *CheckHistory) WarnOrCritical() bool

WarnOrCritical evaluates if all results in history are warn or critical

type Checker

type Checker interface {
	ID() string
	Check(ctx context.Context) *Result
	Interval() time.Duration
	Detector() *Detector
}

type CheckerConfig

type CheckerConfig map[string]any

func (*CheckerConfig) Unmarshal

func (dc *CheckerConfig) Unmarshal(v any) error

type Credentials

type Credentials struct {
	// TODO: must be stored encrypted in DB
	UsernameCrypt string `json:"username_crypt"`
	PasswordCrypt string `json:"password_crypt"`
	// contains filtered or unexported fields
}

func (*Credentials) BasicAuth

func (c *Credentials) BasicAuth() string

func (*Credentials) Decrypt

func (c *Credentials) Decrypt(crypter Crypter)

type Crypter

type Crypter interface {
	Encrypt(text string) (string, error)
	Decrypt(ciphertextHex string) (string, error)
}

type Detector

type Detector struct {
	bun.BaseModel `bun:"table:detectors"`
	ID            uuid.UUID    `json:"id" bun:"type:uuid,pk,default:uuid_generate_v4()"`
	HostID        uuid.UUID    `json:"hostId" bun:"type:uuid"`
	Name          string       `json:"name"`
	HostName      string       `json:"hostName"`
	Active        bool         `json:"active"`
	Type          DetectorType `json:"type"`
	Timeout       Duration     `json:"timeout"`
	Interval      Duration     `json:"interval"`

	Tags []string `json:"tags" bun:",array"`

	// Config is the configuration for the specified checker type which implements also the Checker interface
	Config CheckerConfig `json:"config" bun:"type:jsonb"`

	State         State     `json:"state"`
	StatusMessage string    `json:"statusMessage"`
	LastCheckedAt time.Time `json:"lastCheckedAt"`

	LookupVersion int       `json:"lookupVersion" bun:",default:1"`
	CreatedAt     time.Time `json:"createdAt"`
	UpdatedAt     time.Time `json:"updatedAt"`

	Metrics []MetricPoint `json:"metrics" bun:"-"`
}

Detector represents a Detector to check several endpoints A Detector holds common information and is the database model.

func (*Detector) ApplyIDs

func (d *Detector) ApplyIDs(r *Result) *Result

func (*Detector) GetChecker

func (d *Detector) GetChecker() (Checker, error)

func (*Detector) MetricFiler

func (d *Detector) MetricFiler(timeRange string) *MetricFilter

TODO: should we split it in different buckets?

type DetectorService

type DetectorService interface {
	Create(ctx context.Context, detector *Detector) error
	GetByID(ctx context.Context, id uuid.UUID) (*Detector, error)
	GetByName(ctx context.Context, name string) (*Detector, error)
	Update(ctx context.Context, detector *Detector) error
	DeleteByID(ctx context.Context, id uuid.UUID) (*Detector, error)
	List(ctx context.Context, detectorFilter *filter.DetectorFilter) ([]*Detector, error)
}

DetectorService

type DetectorType

type DetectorType string
var (
	DetectorHTTP     DetectorType = "http"
	DetectorPostgres DetectorType = "psql"
	DetectorAgent    DetectorType = "agent"
)

func (DetectorType) String

func (s DetectorType) String() string

type Duration

type Duration time.Duration

func (Duration) MarshalJSON

func (d Duration) MarshalJSON() ([]byte, error)

JSON

func (Duration) MarshalTOML

func (d Duration) MarshalTOML() ([]byte, error)

TOML

func (Duration) MarshalYAML

func (d Duration) MarshalYAML() (interface{}, error)

YAML

func (Duration) String

func (d Duration) String() string

func (*Duration) UnmarshalJSON

func (d *Duration) UnmarshalJSON(b []byte) error

func (*Duration) UnmarshalTOML

func (d *Duration) UnmarshalTOML(data interface{}) error

func (*Duration) UnmarshalYAML

func (d *Duration) UnmarshalYAML(unmarshal func(interface{}) error) error

type Error

type Error struct {
	// Machine-readable error code.
	Code string
	// Human-readable error message.
	Message string

	// Internal error message - schould not exposed to API user
	Internal error
	// Data can be use in http response body
	Data any
}

Error represents an application-specific error. Application errors can be unwrapped by the caller to extract out the code & message.

Any non-application error (such as a disk error) should be reported as an EINTERNAL error and the human user should only see "Internal error" as the message. These low-level internal error details should only be logged and reported to the operator of the application (not the end user).

func ErrConflictf

func ErrConflictf(format string, args ...any) *Error

func ErrInternalf

func ErrInternalf(format string, args ...any) *Error

func ErrInvalidf

func ErrInvalidf(format string, args ...any) *Error

ErrInvalidf HTTP: BadRequest

func ErrNotImplementedf

func ErrNotImplementedf(format string, args ...any) *Error

func ErrNotfoundf

func ErrNotfoundf(format string, args ...any) *Error

func ErrUnauthorizedf

func ErrUnauthorizedf(format string, args ...any) *Error

func Errorf

func Errorf(code string, format string, args ...any) *Error

Errorf is a helper function to return an Error with a given code and formatted message.

func FromError

func FromError(err error) *Error

FromError creates an Application Error from an error interface

func (*Error) Error

func (e *Error) Error() string

Error implements the error interface. Not used by the application otherwise.

func (*Error) String

func (e *Error) String() string

String returns the whole error message inclusive internal error if exists

func (*Error) WithData

func (e *Error) WithData(data any) *Error

func (*Error) WithError

func (e *Error) WithError(err error) *Error

WithError wraps the error to internal

type EventHandler

type EventHandler interface {
	EventPusher
	EventSubscriber
}

type EventPusher

type EventPusher interface {
	Push(ctx context.Context, topicID string, event *eventflow.Event) error
}

type EventSubscriber

type EventSubscriber interface {
	Subscribe(ctx context.Context, topicID string, onEventFn EventHandler) (*eventflow.Subscription, error)
}

type HTTPAuthType

type HTTPAuthType string
const (
	BearerAuth HTTPAuthType = "bearer-auth"
	BasicAuth  HTTPAuthType = "basic-auth"
)

type HTTPChecker

type HTTPChecker struct {
	Host               string            `json:"host"` // should be come from the Host type, since a dector is always binded to a host
	URL                string            `json:"url"`
	Headers            map[string]string `json:"headers"`
	AuthenticationType HTTPAuthType      `json:"authenticationType"`
	Credentials        Credentials       `json:"credentials"`
	ExpectedBody       string            `json:"expectedBody"`
	ExpectedStatus     int               `json:"expectedStatus"`
	ExpectedHeader     http.Header       `json:"expectedHeader"`
	// contains filtered or unexported fields
}

HTTPChecker implements the checker interface

func (*HTTPChecker) Check

func (hc *HTTPChecker) Check(ctx context.Context) *Result

func (*HTTPChecker) Detector

func (h *HTTPChecker) Detector() *Detector

func (*HTTPChecker) ID

func (hc *HTTPChecker) ID() string

func (*HTTPChecker) Interval

func (hc *HTTPChecker) Interval() time.Duration

func (*HTTPChecker) Validate

func (h *HTTPChecker) Validate() bool

type Host

type Host struct {
	bun.BaseModel `bun:"table:hosts"`
	ID            uuid.UUID   `json:"id" bun:"type:uuid,pk,default:uuid_generate_v4()"`
	LookupVersion int         `json:"lookupVersion" bun:",default:1"`
	Name          string      `json:"name"`
	AddressType   AddressType `json:"addressType"` // IPv4 oder IPv6
	Address       string      `json:"address"`
	Location      string      `json:"location"`
	OS            string      `json:"os"`
	Active        bool        `json:"active"`
	Agent         bool        `json:"agent"`
	State         State       `json:"state"`
	StatusMessage string      `json:"statusMessage"`
	LastCheckedAt time.Time   `json:"lastCheckedAt"`
	Tags          []string    `json:"tags" bun:",array"`

	CreatedAt time.Time `json:"createdAt"`
	UpdatedAt time.Time `json:"updatedAt"`

	Detectors []*Detector `json:"detectors,omitempty" bun:"rel:has-many,join:id=host_id"`
}

Host

type HostService

type HostService interface {
	Create(ctx context.Context, host *Host) error
	GetByID(ctx context.Context, id uuid.UUID) (*Host, error)
	GetByName(ctx context.Context, name string) (*Host, error)
	Update(ctx context.Context, host *Host) error
	DeleteByID(ctx context.Context, id uuid.UUID) (*Host, error)
	List(ctx context.Context, hostFilter *filter.HostFilter) ([]*Host, error)
}

HostService

type Mailer

type Mailer interface {
	SendTemplate(templateFile string, data any) error
}

type Metric

type Metric struct {
	Bucket      string
	Measurement string
	Fields      map[string]any
	Tags        map[string]string
	Time        time.Time
}

func (*Metric) Point

func (m *Metric) Point() *write.Point

type MetricFilter

type MetricFilter struct {
	DetectorID string
	HostID     string
	Bucket     string
	Range      string
	Mesurement string
	Field      string
	Yield      string
}

func (*MetricFilter) Query

func (mf *MetricFilter) Query() string

type MetricPoint

type MetricPoint struct {
	Time   time.Time      `json:"time"`
	Fields map[string]any `json:"fields"`
}

type MetricReader

type MetricReader interface {
	Read(context.Context, *MetricFilter) ([]MetricPoint, error)
}

type MetricService

type MetricService interface {
	MetricWriter
	MetricReader
}

type MetricWriter

type MetricWriter interface {
	Write(context.Context, *Metric) error
}

type Password

type Password struct {
	Plaintext *string
	Hash      []byte
}

func (*Password) Matches

func (p *Password) Matches(plaintextPass string) (bool, error)

func (*Password) Set

func (p *Password) Set(plaintextPass string) error

type PingConfig

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

type PostgresChecker

type PostgresChecker struct {
	Host        string `json:"host"` // should be come from the Host type, since a dector is always binded to a host
	Port        string `json:"port"`
	Database    string `json:"database"`
	SSL         bool   `json:"ssl"`
	Credentials Credentials
	// contains filtered or unexported fields
}

func (*PostgresChecker) Check

func (p *PostgresChecker) Check(ctx context.Context) *Result

func (*PostgresChecker) Detector

func (p *PostgresChecker) Detector() *Detector

func (*PostgresChecker) ID

func (p *PostgresChecker) ID() string

func (*PostgresChecker) Interval

func (p *PostgresChecker) Interval() time.Duration

func (*PostgresChecker) Validate

func (p *PostgresChecker) Validate() bool

type Preference

type Preference struct {
	bun.BaseModel `bun:"table:preferences"`
	ID            uuid.UUID `json:"id" bun:"type:uuid,pk,default:uuid_generate_v4()"`
	LookupVersion int       `json:"lookupVersion" bun:",default:1"`
	Name          string    `json:"name"`
	Value         string    `json:"value"`
	CreatedAt     time.Time `json:"createdAt"`
	UpdatedAt     time.Time `json:"updatedAt"`
}

type PreferenceService

type PreferenceService interface {
	AllPreferences(context.Context) (*Preferences, error)
	GetByName(ctx context.Context, name string) (*Preference, error)
	List(ctx context.Context, prefFilter *filter.PreferenceFilter) (*Preferences, error)
	Set(ctx context.Context, pref *Preference) error
	Update(ctx context.Context, pref *Preference) error
	SetAll(ctx context.Context, prefs *Preferences) error
	DeleteByName(ctx context.Context, name string) error
}

PreferenceService retrieve and set preferences INFO: Preferences are a map and Preference is a struct type

type Preferences

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

Preferences. The map is inside a struct because this way we can change the implementation

func (*Preferences) Crypt

func (p *Preferences) Crypt(crypter Crypter, key string) error

Crypt crypts the value of the given key and removes the uncrypted entry

func (*Preferences) CryptValues

func (p *Preferences) CryptValues(crypter Crypter, suffixe ...string) error

func (*Preferences) Decode

func (p *Preferences) Decode(v any) error

func (*Preferences) Delete

func (p *Preferences) Delete(key string)

func (*Preferences) Get

func (p *Preferences) Get(key string) string

func (*Preferences) Has

func (p *Preferences) Has(key string) bool

func (*Preferences) Map

func (p *Preferences) Map() map[string]string

func (*Preferences) MarshalJSON

func (p *Preferences) MarshalJSON() ([]byte, error)

func (*Preferences) Next

func (p *Preferences) Next() bool

func (*Preferences) Pref

func (p *Preferences) Pref() *Preference

func (*Preferences) Set

func (p *Preferences) Set(key string, value string)

func (*Preferences) UnmarshalJSON

func (p *Preferences) UnmarshalJSON(b []byte) error

func (*Preferences) Validate

func (p *Preferences) Validate(v *validator.Validator)

type PublicUser

type PublicUser struct {
	ID        uuid.UUID `json:"id" bun:"type:uuid,pk,default:uuid_generate_v4()"`
	FirstName string    `json:"first_name"`
	LastName  string    `json:"last_name"`
	Email     string    `json:"email"`
	Activated bool      `json:"activated"`
	CreatedAt time.Time `json:"created_at"`
}

PublicUser represents a public user for this application with limited information

type Recipient

type Recipient struct {
	bun.BaseModel `bun:"table:recipients"`
	ID            uuid.UUID `json:"id" bun:"type:uuid,pk,default:uuid_generate_v4()"`
	LookupVersion int       `json:"lookupVersion" bun:",default:1"`
	Name          string    `json:"first_name"`
	Activated     bool      `json:"activated"`
	Email         string    `json:"email"`
	CreatedAt     time.Time `json:"created_at"`
	UpdatedAt     time.Time `json:"updated_at"`
}

User represents the user for this application

type RecipientService

type RecipientService interface {
	Create(ctx context.Context, rcpt *Recipient) error
	GetByID(ctx context.Context, id uuid.UUID) (*Recipient, error)
	GetByEmail(ctx context.Context, email string) (*Recipient, error)
	Update(ctx context.Context, rcpt *Recipient) error
	DeleteByID(ctx context.Context, id uuid.UUID) (*Recipient, error)
	List(ctx context.Context, rcptFilter *filter.RecipientFilter) ([]*Recipient, error)
}

RecipientService represents a service for managing recipients.

type Result

type Result struct {
	Host     string  `json:"host"`
	Detector string  `json:"detector"`
	State    State   `json:"state"`
	Message  string  `json:"message"`
	Metric   *Metric `json:"metric"`
	// contains filtered or unexported fields
}

func (*Result) Error

func (r *Result) Error() error

func (*Result) String

func (r *Result) String() string

type ResultEvent

type ResultEvent struct {
	HostID       string
	DetectorID   string
	HostName     string
	DetectorName string
	CheckResult  *Result
}

type Role

type Role string
const (
	RoleAdmin   Role = "admin"
	RoleRegular Role = "regular"
)

func (Role) String

func (r Role) String() string

type Session

type Session struct {
	bun.BaseModel `bun:"table:sessions,alias:sessions"`

	Token  string    `json:"token" bun:"-"`
	Hash   []byte    `json:"-" bun:"hash,pk"`
	UserID uuid.UUID `json:"-"`
	Expiry time.Time `json:"expiry" bun:"expiry"`

	User *User `json:"-" bun:"rel:belongs-to,join:user_id=id"`
}

type SessionService

type SessionService interface {
	Put(ctx context.Context, session *Session) error
	Get(ctx context.Context, token string) (*Session, bool, error)
	Delete(ctx context.Context, token string) error
}

type State

type State string

TODO: use int with iota, see below?

const (
	StateOK       State = "OK"
	StateWarn     State = "WARN"
	StateCritical State = "CRITICAL"
	StateInactive State = "INACTIVE"
)

func (State) String

func (s State) String() string

type StateInt

type StateInt int

TODO: use this?

const (
	StateIntInactive StateInt = iota - 1
	StateIntOK
	StateIntWarn
	StateIntCritical
)

type User

type User struct {
	bun.BaseModel `bun:"table:users,alias:u"`
	ID            uuid.UUID `json:"id" bun:"type:uuid,pk,default:uuid_generate_v4()"`
	LookupVersion int       `json:"lookupVersion" bun:",default:1"`
	FirstName     string    `json:"first_name"`
	LastName      string    `json:"last_name"`
	Activated     bool      `json:"activated"`
	Email         string    `json:"email"`
	Password      Password  `json:"-" bun:"-"`
	PasswordHash  []byte    `json:"-"`
	Role          Role      `json:"role"`
	CreatedAt     time.Time `json:"created_at"`
	UpdatedAt     time.Time `json:"updated_at"`
	DeletedAt     time.Time `json:"deleted_at"`
	Image         string    `json:"image" bun:"-"`
}

User represents the user for this application

func UserFromContext

func UserFromContext(ctx context.Context) (*User, error)

UserFromContext returns the current logged in user.

func (*User) IsAdmin

func (user *User) IsAdmin() bool

func (*User) IsAnonymus

func (user *User) IsAnonymus() bool

func (*User) Public

func (user *User) Public() *PublicUser

type UserHostPermissions

type UserHostPermissions struct {
	ID         uuid.UUID
	UserID     uuid.UUID
	HostID     uuid.UUID
	Permission permissions.Permission
}

type UserPermissions

type UserPermissions struct {
	ID            uuid.UUID
	UserID        uuid.UUID
	AppPermission AppPermission
}

type UserService

type UserService interface {
	Create(ctx context.Context, user *User) error
	GetByID(ctx context.Context, id uuid.UUID) (*User, error)
	GetByEmail(ctx context.Context, email string) (*User, error)
	Update(ctx context.Context, user *User) error
	DeleteByID(ctx context.Context, id uuid.UUID) (*User, error)
	List(ctx context.Context, userFilter *filter.UserFilter) ([]*User, error)
}

UserService represents a service for managing users.

type Users

type Users []User

type Validator

type Validator interface {
	Validate() bool
}

Directories

Path Synopsis
Source: https://github.com/benbjohnson/wtf/tree/main
Source: https://github.com/benbjohnson/wtf/tree/main
zog is a wrapper for zerolog
zog is a wrapper for zerolog

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL
JackTT - Gopher 🇻🇳