core

package
v2.0.0-alpha.5 Latest Latest
Warning

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

Go to latest
Published: Jun 1, 2021 License: Apache-2.0 Imports: 20 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// EventKind represents the canonical Event kind string
	EventKind = "Event"

	// CloneLabelKey is the label key used for tracing the original event
	// on any cloned event
	CloneLabelKey = "brigade.sh/cloneOf"

	// RetryLabelKey is the label key used for tracing the original event
	// on any retried event
	RetryLabelKey = "brigade.sh/retryOf"
)
View Source
const (

	// RoleProjectAdmin represents a project-level Role that enables a principal
	// to manage a Project.
	RoleProjectAdmin libAuthz.Role = "PROJECT_ADMIN"

	// RoleProjectDeveloper represents a project-level Role that enables a
	// principal to update a Project.
	RoleProjectDeveloper libAuthz.Role = "PROJECT_DEVELOPER"

	// RoleProjectUser represents a project-level Role that enables a principal to
	// create and manage Events for a Project.
	RoleProjectUser libAuthz.Role = "PROJECT_USER"

	// RoleObserver represents a system-level Role that enables principals to
	// update Worker and Job status based on observation of the underlying
	// workload execution substrate. This Role exists exclusively for use by
	// Brigade's Observer component.
	RoleObserver libAuthz.Role = "OBSERVER"

	// RoleScheduler represents a system-level Role that enables principals to
	// initiate execution of a Worker or Job on the underlying workload execution
	// substrate. This Role exists exclusively for use by Brigade's Scheduler
	// component.
	RoleScheduler libAuthz.Role = "SCHEDULER"

	// RoleWorker represents an event-level Role that enables principals to create
	// new Jobs, monitor the status of those Jobs, and access their logs. This
	// Role is exclusively for the use of Brigade Workers.
	RoleWorker libAuthz.Role = "WORKER"
)
View Source
const (
	// ProjectRoleAssignmentKind represents the canonical ProjectRoleAssignment
	// kind string
	ProjectRoleAssignmentKind = "ProjectRoleAssignment"

	// ProjectRoleAssignmentListKind represents the canonical
	// ProjectRoleAssignmentList kind string
	ProjectRoleAssignmentListKind = "ProjectRoleAssignmentList"
)
View Source
const JobKind = "Job"

JobKind represents the canonical Job kind string

View Source
const ProjectKind = "Project"

ProjectKind represents the canonical Project kind string

View Source
const ProjectRoleScopeGlobal = "*"

ProjectRoleScopeGlobal represents an unbounded project scope.

Variables

This section is empty.

Functions

This section is empty.

Types

type CancelManyEventsResult

type CancelManyEventsResult struct {
	// Count represents the number of Events canceled.
	Count int64 `json:"count"`
}

CancelManyEventsResult represents a summary of a mass Event cancellation operation.

func (CancelManyEventsResult) MarshalJSON

func (c CancelManyEventsResult) MarshalJSON() ([]byte, error)

MarshalJSON amends CancelManyEventsResult instances with type metadata.

type ContainerSpec

type ContainerSpec struct {
	// Image specifies the OCI image on which the container should be based.
	Image string `json:"image,omitempty" bson:"image,omitempty"`
	// ImagePullPolicy specifies whether a container host already having the
	// specified OCI image should attempt to re-pull that image prior to launching
	// a new container.
	ImagePullPolicy ImagePullPolicy `json:"imagePullPolicy,omitempty" bson:"imagePullPolicy,omitempty"` // nolint: lll
	// Command specifies the command to be executed by the OCI container. This
	// can be used to optionally override the default command specified by the OCI
	// image itself.
	Command []string `json:"command,omitempty" bson:"command,omitempty"`
	// Arguments specifies arguments to the command executed by the OCI container.
	Arguments []string `json:"arguments,omitempty" bson:"arguments,omitempty"`
	// Environment is a map of key/value pairs that specify environment variables
	// to be set within the OCI container.
	Environment map[string]string `json:"environment,omitempty" bson:"environment,omitempty"` // nolint: lll
}

ContainerSpec represents the technical details of an OCI container.

type CoolLogsStore

type CoolLogsStore interface {
	LogsStore

	// DeleteEventLogs deletes all logs associated with the provided event.
	DeleteEventLogs(ctx context.Context, id string) error

	// DeleteProjectLogs deletes all logs associated with the provided project.
	DeleteProjectLogs(ctx context.Context, id string) error
}

CoolLogsStore is an interface for components that implement "cool" Log persistence concerns. These log store types are intended to act as longterm storehouses for worker and job logs after they have reached a terminal state. Thus, log deletion methods are prudent for managing the size of the underlying store.

type DeleteManyEventsResult

type DeleteManyEventsResult struct {
	// Count represents the number of Events deleted.
	Count int64 `json:"count"`
}

DeleteManyEventsResult represents a summary of a mass Event deletion operation.

func (DeleteManyEventsResult) MarshalJSON

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

MarshalJSON amends DeleteManyEventsResult instances with type metadata.

type Event

type Event struct {
	// ObjectMeta contains Event metadata.
	meta.ObjectMeta `json:"metadata" bson:",inline"`
	// ProjectID specifies the Project this Event is for. Often, this field will
	// be left blank, in which case the Event is matched against subscribed
	// Projects on the basis of the Source, Type, Qualifiers, and Labels fields,
	// then used as a template to create a discrete Event for each subscribed
	// Project.
	ProjectID string `json:"projectID,omitempty" bson:"projectID,omitempty"`
	// Source specifies the source of the Event, e.g. what gateway created it.
	// Gateways should populate this field with a unique string that clearly
	// identifies themself as the source of the event. The ServiceAccount used by
	// each gateway can be authorized (by a admin) to only create events having a
	// specified value in the Source field, thereby eliminating the possibility of
	// gateways maliciously creating events that spoof events from another
	// gateway.
	Source string `json:"source,omitempty" bson:"source,omitempty"`
	// SourceState encapsulates opaque, source-specific (e.g. gateway-specific)
	// state.
	SourceState *SourceState `json:"sourceState,omitempty" bson:"sourceState,omitempty"` // nolint: lll
	// Type specifies the exact event that has occurred in the upstream system.
	// Values are opaque and source-specific.
	Type string `json:"type,omitempty" bson:"type,omitempty"`
	// Qualifiers provide critical disambiguation of an Event's type. A Project is
	// considered subscribed to an Event IF AND ONLY IF (in addition to matching
	// the Event's Source and Type) it matches ALL of the Event's qualifiers
	// EXACTLY. To demonstrate the usefulness of this, consider any event from a
	// hypothetical GitHub gateway. If, by design, that gateway does not intend
	// for any Project to subscribe to ALL Events (i.e. regardless of which
	// repository they originated from), then that gateway can QUALIFY Events it
	// emits into Brigade's event bus with repo=<repository name>. Projects
	// wishing to subscribe to Events from the GitHub gateway MUST include that
	// Qualifier in their EventSubscription. Note that the Qualifiers field's
	// "MUST match" subscription semantics differ from the Labels field's "MAY
	// match" subscription semantics.
	Qualifiers Qualifiers `json:"qualifiers,omitempty" bson:"qualifiers,omitempty"` // nolint: lll
	// Labels convey supplementary Event details that Projects may OPTIONALLY use
	// to narrow EventSubscription criteria. A Project is considered subscribed to
	// an Event if (in addition to matching the Event's Source, Type, and
	// Qualifiers) the Event has ALL labels expressed in the Project's
	// EventSubscription. If the Event has ADDITIONAL labels, not mentioned by the
	// EventSubscription, these do not preclude a match. To demonstrate the
	// usefulness of this, consider any event from a hypothetical Slack gateway.
	// If, by design, that gateway intends for Projects to select between
	// subscribing to ALL Events or ONLY events originating from a specific
	// channel, then that gateway can LABEL Events it emits into Brigade's event
	// bus with channel=<channel name>. Projects wishing to subscribe to ALL
	// Events from the Slack gateway MAY omit that Label from their
	// EventSubscription, while Projects wishing to subscribe to only Events
	// originating from a specific channel MAY include that Label in their
	// EventSubscription. Note that the Labels field's "MAY match" subscription
	// semantics differ from the Qualifiers field's "MUST match" subscription
	// semantics.
	Labels map[string]string `json:"labels,omitempty" bson:"labels,omitempty"`
	// ShortTitle is an optional, succinct title for the Event, ideal for use in
	// lists or in scenarios where UI real estate is constrained.
	ShortTitle string `json:"shortTitle,omitempty" bson:"shortTitle,omitempty"`
	// LongTitle is an optional, detailed title for the Event.
	LongTitle string `json:"longTitle,omitempty" bson:"longTitle,omitempty"`
	// Git contains git-specific Event details. These can be used to override
	// similar details defined at the Project level. This is useful for scenarios
	// wherein an Event may need to convey an alternative source, branch, etc.
	Git *GitDetails `json:"git,omitempty" bson:"git,omitempty"`
	// Payload optionally contains Event details provided by the upstream system
	// that was the original source of the event. Payloads MUST NOT contain
	// sensitive information. Since Projects SUBSCRIBE to Events, the potential
	// exists for any Project to express an interest in any or all Events. This
	// being the case, sensitive details must never be present in payloads. The
	// common workaround work this constraint (which is also a sensible practice
	// to begin with) is that event payloads may contain REFERENCES to sensitive
	// details that are useful only to properly configured Workers.
	Payload string `json:"payload,omitempty" bson:"payload,omitempty"`
	// Worker contains details of the Worker assigned to handle the Event.
	Worker Worker `json:"worker" bson:"worker"`
}

Event represents an occurrence in some upstream system. Once accepted into the system, Brigade amends each Event with a plan for handling it in the form of a Worker. An Event's status is, implicitly, the status of its Worker.

func (Event) MarshalJSON

func (e Event) MarshalJSON() ([]byte, error)

MarshalJSON amends Event instances with type metadata.

type EventList

type EventList struct {
	// ListMeta contains list metadata.
	meta.ListMeta `json:"metadata"`
	// Items is a slice of Events.
	Items []Event `json:"items,omitempty"`
}

EventList is an ordered and pageable list of Events.

func (EventList) MarshalJSON

func (e EventList) MarshalJSON() ([]byte, error)

MarshalJSON amends EventList instances with type metadata.

type EventSubscription

type EventSubscription struct {
	// Source specifies the origin of an Event (e.g. a gateway). This is a
	// required field.
	Source string `json:"source,omitempty" bson:"source,omitempty"`
	// Types enumerates specific Events of interest from the specified Source.
	// This is useful in narrowing a subscription when a Source also emits many
	// Event types that are NOT of interest. This is a required field. The value
	// "*" may be utilized to denote that ALL events originating from the
	// specified Source are of interest.
	Types []string `json:"types,omitempty" bson:"types,omitempty"`
	// Qualifiers specifies an EXACT set of key/value pairs with which an Event
	// MUST also be qualified for a Project to be considered subscribed. To
	// demonstrate the usefulness of this, consider any event from a hypothetical
	// GitHub gateway. If, by design, that gateway does not intend for any Project
	// to subscribe to ALL Events (i.e. regardless of which repository they
	// originated from), then that gateway can QUALIFY Events it emits into
	// Brigade's event bus with repo=<repository name>. Projects wishing to
	// subscribe to Events from the GitHub gateway MUST include that Qualifier in
	// their EventSubscription. Note that the Qualifiers field's "MUST match"
	// subscription semantics differ from the Labels field's "MAY match"
	// subscription semantics.
	Qualifiers Qualifiers `json:"qualifiers,omitempty" bson:"qualifiers,omitempty"` // nolint: lll
	// Labels optionally specifies filter criteria as key/value pairs with which
	// an Event MUST also be labeled for a Project to be considered subscribed. If
	// the Event has ADDITIONAL labels, not mentioned by this EventSubscription,
	// these do not preclude a match. To demonstrate the usefulness of this,
	// consider any event from a hypothetical Slack gateway. If, by design, that
	// gateway intends for Projects to select between subscribing to ALL Events or
	// ONLY events originating from a specific channel, then that gateway can
	// LABEL Events it emits into Brigade's event bus with channel=<channel name>.
	// Projects wishing to subscribe to ALL Events from the Slack gateway MAY omit
	// that Label from their EventSubscription, while Projects wishing to
	// subscribe to only Events originating from a specific channel MAY include
	// that Label in their EventSubscription. Note that the Labels field's "MAY
	// match" subscription semantics differ from the Qualifiers field's "MUST
	// match" subscription semantics.
	Labels map[string]string `json:"labels,omitempty" bson:"labels,omitempty"`
}

EventSubscription defines a set of Events of interest. ProjectSpecs utilize these in defining the Events that should trigger the execution of a new Worker. An Event matches a subscription if it meets ALL of the specified criteria.

type EventsSelector

type EventsSelector struct {
	// ProjectID specifies that only Events belonging to the indicated Project
	// should be selected.
	ProjectID string
	// Source specifies that only Events from the indicated source should be
	// selected.
	Source string
	// SourceState specifies that only Events having all of the indicated source
	// state key/value pairs should be selected.
	SourceState map[string]string
	// Type specifies that only Events having the indicated type should be
	// selected.
	Type string
	// WorkerPhases specifies that only Events with their Workers in any of the
	// indicated phases should be selected.
	WorkerPhases []WorkerPhase
	// Qualifiers specifies that only Events qualified with these key/value pairs
	// should be selected.
	Qualifiers Qualifiers
	// Labels specifies that only Events labeled with these key/value pairs should
	// be selected.
	Labels map[string]string
}

EventsSelector represents useful filter criteria when selecting multiple Events for API group operations like list, cancel, or delete.

type EventsService

type EventsService interface {
	// Create creates a new Event.
	Create(context.Context, Event) (
		EventList,
		error,
	)
	// List retrieves an EventList, with its Items (Events) ordered by age, newest
	// first. Criteria for which Events should be retrieved can be specified using
	// the EventListOptions parameter.
	List(
		context.Context,
		EventsSelector,
		meta.ListOptions,
	) (EventList, error)
	// Get retrieves a single Event specified by its identifier. If no such event
	// is found, implementations MUST return a *meta.ErrNotFound error.
	Get(context.Context, string) (Event, error)
	// GetByWorkerToken retrieves a single Event specified by its Worker's token.
	// If no such event is found, implementations MUST return a *meta.ErrNotFound
	// error.
	GetByWorkerToken(context.Context, string) (Event, error)
	// Clones an Event and creates a new Event after removing the original's
	// metadata and Worker configuration
	Clone(context.Context, string) (Event, error)
	// UpdateSourceState updates source-specific (e.g. gateway-specific) Event
	// state.
	UpdateSourceState(context.Context, string, SourceState) error
	// Cancel cancels a single Event specified by its identifier. If no such event
	// is found, implementations MUST return a *meta.ErrNotFound error.
	// Implementations MUST only cancel events whose Workers have not already
	// reached a terminal state. If the specified Event's Worker has already
	// reached a terminal state, implementations MUST return a *meta.ErrConflict.
	Cancel(context.Context, string) error
	// CancelMany cancels multiple Events specified by the EventsSelector
	// parameter. Implementations MUST only cancel events whose Workers have not
	// already reached a terminal state.
	CancelMany(
		context.Context,
		EventsSelector,
	) (CancelManyEventsResult, error)
	// Delete unconditionally deletes a single Event specified by its identifier.
	// If no such event is found, implementations MUST return a *meta.ErrNotFound
	// error.
	Delete(context.Context, string) error
	// DeleteMany unconditionally deletes multiple Events specified by the
	// EventsSelector parameter.
	DeleteMany(
		context.Context,
		EventsSelector,
	) (DeleteManyEventsResult, error)
	// Retry copies an Event, including Worker configuration and Jobs, and
	// creates a new Event from this information.  Where possible, job results
	// are inherited and the job not re-scheduled, for example when a job has
	// succeeded and does not make use of a shared workspace.
	Retry(context.Context, string) (Event, error)
}

EventsService is the specialized interface for managing Events. It's decoupled from underlying technology choices (e.g. data store, message bus, etc.) to keep business logic reusable and consistent while the underlying tech stack remains free to change.

func NewEventsService

func NewEventsService(
	authorizeFn libAuthz.AuthorizeFn,
	projectAuthorize ProjectAuthorizeFn,
	projectsStore ProjectsStore,
	eventsStore EventsStore,
	logsStore CoolLogsStore,
	substrate Substrate,
) EventsService

NewEventsService returns a specialized interface for managing Events.

type EventsStore

type EventsStore interface {
	// Create persists a new Event in the underlying data store. If n Event having
	// the same ID already exists, implementations MUST return a *meta.ErrConflict
	// error.
	Create(context.Context, Event) error
	// List retrieves an EventList from the underlying data store, with its Items
	// (Events) ordered by age, newest first. Criteria for which Events should be
	// retrieved can be specified using the EventListOptions parameter.
	List(
		context.Context,
		EventsSelector,
		meta.ListOptions,
	) (EventList, error)
	// Get retrieves a single Event from the underlying data store. If the
	// specified Event does not exist, implementations MUST return a
	// *meta.ErrNotFound error.
	Get(context.Context, string) (Event, error)
	// GetByHashedWorkerToken retrieves a single Event from the underlying data
	// store by the provided hashed Worker token. If no such Event exists,
	// implementations MUST return a *meta.ErrNotFound error.
	GetByHashedWorkerToken(context.Context, string) (Event, error)
	// UpdateSourceState updates source-specific (e.g. gateway-specific) Event
	// state. Implementations MAY assume the Event's existence has been
	// pre-confirmed by the caller.
	UpdateSourceState(context.Context, string, SourceState) error
	// Cancel updates the specified Event in the underlying data store to reflect
	// that it has been canceled. Implementations MAY assume the Event's existence
	// has been pre-confirmed by the caller. Implementations MUST only cancel
	// events whose Workers have not already reached a terminal state. If the
	// specified Event's Worker has already reached a terminal state,
	// implementations MUST return a *meta.ErrConflict.
	Cancel(context.Context, string) error
	// CancelMany updates multiple Events specified by the EventsSelector
	// parameter in the underlying data store to reflect that they have been
	// canceled. Implementations MUST only cancel events whose Workers have not
	// already reached a terminal state and MUST return the total number of
	// canceled events.
	CancelMany(context.Context, EventsSelector) (<-chan Event, int64, error)
	// Delete unconditionally deletes the specified Event from the underlying data
	// store. If the specified Event does not exist, implementations MUST
	// return a *meta.ErrNotFound error.
	Delete(context.Context, string) error
	// DeleteMany unconditionally deletes multiple Events specified by the
	// EventsSelector parameter from the underlying data store.  Implementations
	// MUST return the total number of deleted events.
	DeleteMany(context.Context, EventsSelector) (<-chan Event, int64, error)
}

EventsStore is an interface for components that implement Event persistence concerns.

type GitConfig

type GitConfig struct {
	// CloneURL specifies the location from where a source code repository may
	// be cloned.
	CloneURL string `json:"cloneURL,omitempty" bson:"cloneURL,omitempty"`
	// Commit specifies a revision (by SHA) to be checked out. If non-empty, this
	// field takes precedence over any value in the Ref field.
	Commit string `json:"commit,omitempty" bson:"commit,omitempty"`
	// Ref is a symbolic reference to a revision to be checked out. If non-empty,
	// the value of the Commit field supercedes any value in this field. Example
	// uses of this field include referencing a branch (refs/heads/<branch name>)
	// or a tag (refs/tags/<tag name>). If left blank, the default value
	// refs/heads/master will be assumed at runtime.
	Ref string `json:"ref,omitempty" bson:"ref,omitempty"`
	// InitSubmodules indicates whether to clone the repository's submodules.
	InitSubmodules bool `json:"initSubmodules" bson:"initSubmodules"`
}

GitConfig represents git-specific Worker details.

type GitDetails

type GitDetails struct {
	// CloneURL specifies the location from where a source code repository may
	// be cloned.
	CloneURL string `json:"cloneURL,omitempty" bson:"cloneURL,omitempty"`
	// Commit specifies a commit (by sha) to be checked out.
	Commit string `json:"commit,omitempty" bson:"commit,omitempty"`
	// Ref specifies a tag or branch to be checked out. If left blank, this will
	// default to "master" at runtime.
	Ref string `json:"ref,omitempty" bson:"ref,omitempty"`
}

GitDetails represents git-specific Event details. These may override Project-level GitConfig.

type ImagePullPolicy

type ImagePullPolicy string

ImagePullPolicy represents a policy for whether container hosts already having a certain OCI image should attempt to re-pull that image prior to launching a new container based on that image.

type Job

type Job struct {
	// Name is the Job's name. It should be unique among a given Worker's Jobs.
	Name string `json:"name" bson:"name"`
	// Spec is the technical blueprint for the Job.
	Spec JobSpec `json:"spec" bson:"spec"`
	// Status contains details of the Job's current state.
	Status *JobStatus `json:"status" bson:"status"`
}

Job represents a component spawned by a Worker to complete a single task in the course of handling an Event.

func (Job) UsesWorkspace

func (j Job) UsesWorkspace() bool

UsesWorkspace returns a boolean value indicating whether or not the job uses a shared workspace.

type JobContainerSpec

type JobContainerSpec struct {
	// ContainerSpec encapsulates generic specifications for an OCI container.
	ContainerSpec `json:",inline" bson:",inline"`
	// WorkingDirectory specifies the OCI container's working directory.
	WorkingDirectory string `json:"workingDirectory,omitempty" bson:"workingDirectory,omitempty"` // nolint: lll
	// WorkspaceMountPath specifies the path in the OCI container's file system
	// where, if applicable, the Worker's shared workspace should be mounted. If
	// left blank, the Job implicitly does not use the Worker's shared workspace.
	WorkspaceMountPath string `json:"workspaceMountPath,omitempty" bson:"workspaceMountPath,omitempty"` // nolint: lll
	// SourceMountPath specifies the path in the OCI container's file system
	// where, if applicable, source code retrieved from a VCS repository should be
	// mounted. If left blank, the Job implicitly does not use source code
	// retrieved from a VCS repository.
	SourceMountPath string `json:"sourceMountPath,omitempty" bson:"sourceMountPath,omitempty"` // nolint: lll
	// Privileged indicates whether the OCI container should operate in a
	// "privileged" (relaxed permissions) mode. This is commonly used to effect
	// "Docker-in-Docker" ("DinD") scenarios wherein one of a Job's OCI containers
	// must run its own Docker daemon. Note this field REQUESTS privileged status
	// for the container, but that may be disallowed by Project-level
	// configuration.
	Privileged bool `json:"privileged" bson:"privileged"`
	// UseHostDockerSocket indicates whether the OCI container should mount the
	// host's Docker socket into its own file system. This is commonly used to
	// effect "Docker-out-of-Docker" ("DooD") scenarios wherein one of a Job's OCI
	// containers must utilize the host's Docker daemon. GENERALLY, THIS IS HIGHLY
	// DISCOURAGED. Note this field REQUESTS to mount the host's Docker socket
	// into the container, but that may be disallowed by Project-level
	// configuration.
	UseHostDockerSocket bool `json:"useHostDockerSocket" bson:"useHostDockerSocket"` // nolint: lll
}

JobContainerSpec amends the ContainerSpec type with additional Job-specific fields.

type JobHost

type JobHost struct {
	// OS specifies which "family" of operating system is required on a substrate
	// node to host a Job. Valid values are "linux" and "windows". When empty,
	// Brigade assumes "linux".
	OS string `json:"os,omitempty" bson:"os,omitempty"`
	// NodeSelector specifies labels that must be present on the substrate node to
	// host a Job. This provides an opaque mechanism for communicating Job needs
	// such as specific hardware like an SSD or GPU.
	NodeSelector map[string]string `json:"nodeSelector,omitempty" bson:"nodeSelector,omitempty"` // nolint: lll
}

JobHost represents criteria for selecting a suitable host (substrate node) for a Job.

type JobPhase

type JobPhase string

JobPhase represents where a Job is within its lifecycle.

const (
	// JobPhaseAborted represents the state wherein a Job was forcefully
	// stopped during execution.
	JobPhaseAborted JobPhase = "ABORTED"
	// JobPhaseCanceled represents the state wherein a pending Job was
	// canceled prior to execution.
	JobPhaseCanceled JobPhase = "CANCELED"
	// JobPhaseFailed represents the state wherein a Job has run to
	// completion but experienced errors.
	JobPhaseFailed JobPhase = "FAILED"
	// JobPhasePending represents the state wherein a Job is awaiting
	// execution.
	JobPhasePending JobPhase = "PENDING"
	// JobPhaseRunning represents the state wherein a Job is currently
	// being executed.
	JobPhaseRunning JobPhase = "RUNNING"
	// JobPhaseSchedulingFailed represents the state wherein a Job was not
	// scheduled due to some unexpected and unrecoverable error encountered by the
	// scheduler.
	JobPhaseSchedulingFailed JobPhase = "SCHEDULING_FAILED"
	// JobPhaseStarting represents the state wherein a Job is starting on the
	// substrate but isn't running yet.
	JobPhaseStarting JobPhase = "STARTING"
	// JobPhaseSucceeded represents the state where a Job has run to
	// completion without error.
	JobPhaseSucceeded JobPhase = "SUCCEEDED"
	// JobPhaseTimedOut represents the state wherein a Job has has not completed
	// within a designated timeframe.
	JobPhaseTimedOut JobPhase = "TIMED_OUT"
	// JobPhaseUnknown represents the state wherein a Job's state is unknown. Note
	// that this is possible if and only if the underlying Job execution substrate
	// (Kubernetes), for some unanticipated, reason does not know the Job's
	// (Pod's) state.
	JobPhaseUnknown JobPhase = "UNKNOWN"
)

func (JobPhase) IsTerminal

func (j JobPhase) IsTerminal() bool

IsTerminal returns a bool indicating whether the JobPhase is terminal.

type JobPolicies

type JobPolicies struct {
	// AllowPrivileged specifies whether the Worker is permitted to launch Jobs
	// that utilize privileged containers.
	AllowPrivileged bool `json:"allowPrivileged" bson:"allowPrivileged"`
	// AllowDockerSocketMount specifies whether the Worker is permitted to launch
	// Jobs that mount the underlying host's Docker socket into its own file
	// system.
	AllowDockerSocketMount bool `json:"allowDockerSocketMount" bson:"allowDockerSocketMount"` // nolint: lll
}

JobPolicies represents policies for any Jobs spawned by a Worker.

type JobSpec

type JobSpec struct {
	// PrimaryContainer specifies the details of an OCI container that forms the
	// cornerstone of the Job. Job success or failure is tied to completion and
	// exit code of this container.
	PrimaryContainer JobContainerSpec `json:"primaryContainer" bson:"primaryContainer"` // nolint: lll
	// SidecarContainers specifies the details of supplemental, "sidecar"
	// containers. Their completion and exit code do not directly impact Job
	// status. Brigade does not understand dependencies between a Job's multiple
	// containers and cannot enforce any specific startup or shutdown order. When
	// such dependencies exist (for instance, a primary container than cannot
	// proceed with a suite of tests until a database is launched and READY in a
	// sidecar container), then logic within those containers must account for
	// these constraints.
	SidecarContainers map[string]JobContainerSpec `json:"sidecarContainers,omitempty" bson:"sidecarContainers,omitempty"` // nolint: lll
	// TimeoutDuration specifies the time duration that must elapse before a
	// running Job should be considered to have timed out. This duration string
	// is a sequence of decimal numbers, each with optional fraction and a unit
	// suffix, such as "300ms", "3.14s" or "2h45m".
	// Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
	TimeoutDuration string `json:"timeoutDuration,omitempty" bson:"timeoutDuration,omitempty"` // nolint: lll
	// Host specifies criteria for selecting a suitable host (substrate node) for
	// the Job. This is useful in cases where a Job requires a specific,
	// non-default operating system (i.e. Windows) or specific hardware (e.g. a
	// GPU.)
	Host *JobHost `json:"host,omitempty" bson:"host,omitempty"`
}

JobSpec is the technical blueprint for a Job.

type JobStatus

type JobStatus struct {
	// Started indicates the time the Job began execution.
	Started *time.Time `json:"started,omitempty" bson:"started,omitempty"`
	// Ended indicates the time the Job concluded execution. It will be nil
	// for a Job that is not done executing.
	Ended *time.Time `json:"ended,omitempty" bson:"ended,omitempty"`
	// Phase indicates where the Job is in its lifecycle.
	Phase JobPhase `json:"phase,omitempty" bson:"phase,omitempty"`
	// LogsEventID indicates which event ID the job logs are associated with.
	// This is useful for looking up logs for an inherited job associated with
	// retry events.
	LogsEventID string `json:"logsEventID,omitempty" bson:"logsEventID,omitempty"`
}

JobStatus represents the status of a Job.

type JobsService

type JobsService interface {
	// Create, given an Event identifier and Job, creates a new Job and schedules
	// it on Brigade's workload execution substrate. If the specified Event does
	// not exist, implementations MUST return a *meta.ErrNotFound error. If the
	// specified Event already has a Job with the specified name, implementations
	// MUST return a *meta.ErrConflict error.
	Create(ctx context.Context, eventID string, job Job) error
	// Start, given an Event identifier and Job name, starts that Job on
	// Brigade's workload execution substrate. If the specified Event or specified
	// Job thereof does not exist, implementations MUST return a *meta.ErrNotFound
	// error.
	Start(ctx context.Context, eventID string, jobName string) error
	// GetStatus, given an Event identifier and Job name, returns the Job's
	// status. If the specified Event or specified Job thereof does not exist,
	// implementations MUST return a *meta.ErrNotFound error.
	GetStatus(
		ctx context.Context,
		eventID string,
		jobName string,
	) (JobStatus, error)
	// WatchStatus, given an Event identifier and Job name, returns a channel over
	// which the Job's status is streamed. The channel receives a new JobStatus
	// every time there is any change in that status. If the specified Event or
	// specified Job thereof does not exist, implementations MUST return a
	// *meta.ErrNotFound error.
	WatchStatus(
		ctx context.Context,
		eventID string,
		jobName string,
	) (<-chan JobStatus, error)
	// UpdateStatus, given an Event identifier and Job name, updates the status of
	// that Job. If the specified Event or specified Job thereof does not exist,
	// implementations MUST return a *meta.ErrNotFound error.
	UpdateStatus(
		ctx context.Context,
		eventID string,
		jobName string,
		status JobStatus,
	) error
	// Cleanup removes Job-related resources from the substrate, presumably
	// upon completion, without deleting the Job from the data store.
	Cleanup(ctx context.Context, eventID, jobName string) error
	// Timeout updates a Job's status to indicate it has timed out and proceeds
	// to cleanup Job-related resources from the substrate.
	Timeout(ctx context.Context, eventID, jobName string) error
}

JobsService is the specialized interface for managing Jobs. It's decoupled from underlying technology choices (e.g. data store, message bus, etc.) to keep business logic reusable and consistent while the underlying tech stack remains free to change.

func NewJobsService

func NewJobsService(
	authorizeFn libAuthz.AuthorizeFn,
	projectsStore ProjectsStore,
	eventsStore EventsStore,
	jobsStore JobsStore,
	substrate Substrate,
) JobsService

NewJobsService returns a specialized interface for managing Jobs.

type JobsStore

type JobsStore interface {
	// Create persists a new Job for the specified Event in the underlying data
	// store.
	Create(ctx context.Context, eventID string, job Job) error
	// UpdateStatus updates the status of the specified Job in the underlying data
	// store. If the specified job is not found, implementations MUST return a
	// *meta.ErrNotFound error.
	UpdateStatus(
		ctx context.Context,
		eventID string,
		jobName string,
		status JobStatus,
	) error
}

JobsStore is an interface for components that implement Job persistence concerns.

type KubernetesConfig

type KubernetesConfig struct {
	// ImagePullSecrets enumerates any image pull secrets that Kubernetes may use
	// when pulling the OCI image on which a Worker's or Job's container is based.
	// This field only needs to be utilized in the case of private, custom Worker
	// or Job images. The image pull secrets in question must be created
	// out-of-band by a sufficiently authorized user of the Kubernetes cluster.
	ImagePullSecrets []string `json:"imagePullSecrets,omitempty" bson:"imagePullSecrets,omitempty"` // nolint: lll
}

KubernetesConfig represents Kubernetes-specific Worker or Job configuration.

type KubernetesDetails

type KubernetesDetails struct {
	// Namespace is the dedicated Kubernetes namespace for the Project. This is
	// NOT specified by clients when creating a new Project. The namespace is
	// created by / assigned by the system. This detail is a necessity to prevent
	// clients from naming existing namespaces in an attempt to hijack them.
	Namespace string `json:"namespace,omitempty" bson:"namespace,omitempty"`
}

KubernetesDetails represents Kubernetes-specific configuration.

type LogEntry

type LogEntry struct {
	// Time is the time the line was written.
	Time *time.Time `json:"time,omitempty" bson:"time,omitempty"`
	// Message is a single line of log output from an OCI container.
	Message string `json:"message,omitempty" bson:"log,omitempty"`
}

LogEntry represents one line of output from an OCI container.

func (LogEntry) MarshalJSON

func (l LogEntry) MarshalJSON() ([]byte, error)

MarshalJSON amends LogEntry instances with type metadata so that clients do not need to be concerned with the tedium of doing so.

type LogLevel

type LogLevel string

LogLevel represents the desired granularity of Worker log output.

const LogLevelInfo LogLevel = "INFO"

LogLevelInfo represents INFO level granularity in Worker log output.

type LogStreamOptions

type LogStreamOptions struct {
	// Follow indicates whether the stream should conclude after the last
	// available line of logs has been sent to the client (false) or remain open
	// until closed by the client (true), continuing to send new lines as they
	// become available.
	Follow bool `json:"follow"`
}

LogStreamOptions represents useful options for streaming logs from some container of a Worker or Job.

type LogsSelector

type LogsSelector struct {
	// Job specifies, by name, a Job spawned by some Worker. If not specified, log
	// streaming operations presume logs are desired for the Worker itself.
	Job string
	// Container specifies, by name, a container belonging to some Worker or, if
	// Job is specified, that Job. If not specified, log streaming operations
	// presume logs are desired from a container having the same name as the
	// selected Worker or Job.
	Container string
}

LogsSelector represents useful criteria for selecting logs to be streamed from any container belonging to some Worker OR any container belonging to Jobs spawned by that Worker.

type LogsService

type LogsService interface {
	// Stream returns a channel over which logs for an Event's Worker, or using
	// the LogsSelector parameter, a Job spawned by that Worker (or specific
	// container thereof), are streamed. If the specified Event, Job, or Container
	// thereof does not exist, implementations MUST return a *meta.ErrNotFound
	// error.
	Stream(
		ctx context.Context,
		eventID string,
		selector LogsSelector,
		opts LogStreamOptions,
	) (<-chan LogEntry, error)
}

LogsService is the specialized interface for accessing logs. It's decoupled from underlying technology choices (e.g. data store, message bus, etc.) to keep business logic reusable and consistent while the underlying tech stack remains free to change.

func NewLogsService

func NewLogsService(
	authorize libAuthz.AuthorizeFn,
	projectAuthorize ProjectAuthorizeFn,
	projectsStore ProjectsStore,
	eventsStore EventsStore,
	warmLogsStore LogsStore,
	coolLogsStore LogsStore,
) LogsService

NewLogsService returns a specialized interface for accessing logs.

type LogsStore

type LogsStore interface {
	// Stream returns a channel over which logs for an Event's Worker, or using
	// the LogsSelector parameter, a Job spawned by that Worker (or specific
	// container thereof), are streamed. If the specified Event, Job, or Container
	// thereof does not exist, implementations MUST return a *meta.ErrNotFound
	// error.
	StreamLogs(
		ctx context.Context,
		project Project,
		event Event,
		selector LogsSelector,
		opts LogStreamOptions,
	) (<-chan LogEntry, error)
}

LogsStore is an interface for components that implement Log persistence concerns.

type Project

type Project struct {
	// ObjectMeta contains Project metadata.
	meta.ObjectMeta `json:"metadata" bson:",inline"`
	// Description is a natural language description of the Project.
	Description string `json:"description,omitempty" bson:"description,omitempty"`
	// Spec is an instance of a ProjectSpec that pairs EventSubscriptions with
	// a WorkerTemplate.
	Spec ProjectSpec `json:"spec" bson:"spec"`
	// Kubernetes contains Kubernetes-specific details of the Project's
	// environment. These details are populated by Brigade so that sufficiently
	// authorized Kubernetes users may obtain the information needed to directly
	// modify a Project's environment to facilitate certain advanced use cases.
	Kubernetes *KubernetesDetails `json:"kubernetes,omitempty" bson:"kubernetes,omitempty"` // nolint: lll
}

Project is Brigade's fundamental configuration, management, and isolation construct.

  • Configuration: Users define Projects to pair EventSubscriptions with template WorkerSpecs.
  • Management: Project administrators govern Project access by granting and revoking project-level Roles to/from principals (such as Users or ServiceAccounts)
  • Isolation: All workloads (Workers and Jobs) spawned to handle a given Project's Events are isolated from other Projects' workloads in the underlying workload execution substrate.

func (Project) MarshalJSON

func (p Project) MarshalJSON() ([]byte, error)

MarshalJSON amends Project instances with type metadata.

type ProjectAuthorizeFn

type ProjectAuthorizeFn func(
	ctx context.Context,
	projectID string,
	role libAuthz.Role,
) error

ProjectAuthorizeFn is the signature for any function that can, presumably, retrieve a principal from the provided Context and make an access control decision based on the principal having (or not having) the specified Role for the specified Project. Implementations MUST return a *meta.ErrAuthorization error if the principal is not authorized.

type ProjectAuthorizer

type ProjectAuthorizer interface {
	// Authorize retrieves a principal from the provided Context and asserts that
	// it has the specified Role for the specified Project. If it does not,
	// implementations MUST return a *meta.ErrAuthorization error.
	Authorize(ctx context.Context, projectID string, role libAuthz.Role) error
}

ProjectAuthorizer is the public interface for the component returned by the NewProjectAuthorizer function.

func NewProjectAuthorizer

func NewProjectAuthorizer(
	projectRoleAssignmentsStore ProjectRoleAssignmentsStore,
) ProjectAuthorizer

NewProjectAuthorizer returns a component that can authorize a request.

type ProjectList

type ProjectList struct {
	// ListMeta contains list metadata.
	meta.ListMeta `json:"metadata"`
	// Items is a slice of Projects.
	Items []Project `json:"items"`
}

ProjectList is an ordered and pageable list of Projects.

func (ProjectList) MarshalJSON

func (p ProjectList) MarshalJSON() ([]byte, error)

MarshalJSON amends ProjectList instances with type metadata.

type ProjectRoleAssignment

type ProjectRoleAssignment struct {
	// ProjectID qualifies the scope of the Role.
	ProjectID string `json:"-" bson:"projectID,omitempty"`
	// Role assigns a Role to the specified principal.
	Role libAuthz.Role `json:"role" bson:"role"`
	// Principal specifies the principal to whom the Role is assigned.
	Principal libAuthz.PrincipalReference `json:"principal" bson:"principal"`
}

ProjectRoleAssignment represents the assignment of a project-level Role to a principal such as a User or ServiceAccount.

func (ProjectRoleAssignment) MarshalJSON

func (p ProjectRoleAssignment) MarshalJSON() ([]byte, error)

MarshalJSON amends ProjectRoleAssignment instances with type metadata.

func (ProjectRoleAssignment) Matches

func (p ProjectRoleAssignment) Matches(
	projectID string,
	role libAuthz.Role,
) bool

Matches determines if this ProjectRoleAssignment matches the projectID and role arguments.

type ProjectRoleAssignmentList

type ProjectRoleAssignmentList struct {
	// ListMeta contains list metadata.
	meta.ListMeta `json:"metadata"`
	// Items is a slice of ProjectRoleAssignments.
	Items []ProjectRoleAssignment `json:"items,omitempty"`
}

ProjectRoleAssignmentList is an ordered and pageable list of ProjectRoleAssignments.

func (ProjectRoleAssignmentList) MarshalJSON

func (p ProjectRoleAssignmentList) MarshalJSON() ([]byte, error)

MarshalJSON amends ProjectRoleAssignmentList instances with type metadata.

type ProjectRoleAssignmentsSelector

type ProjectRoleAssignmentsSelector struct {
	// Principal specifies that only ProjectRoleAssignments for the specified
	// principal should be selected.
	Principal *libAuthz.PrincipalReference
	// ProjectID specifies that only ProjectRoleAssignments for the specified
	// Project should be selected.
	ProjectID string
	// Role specifies that only ProjectRoleAssignments for the specified
	// Role should be selected.
	Role libAuthz.Role
}

ProjectRoleAssignmentsSelector represents useful filter criteria when selecting multiple ProjectRoleAssignments for API group operations like list.

type ProjectRoleAssignmentsService

type ProjectRoleAssignmentsService interface {
	// Grant grants the project-level Role specified by the ProjectRoleAssignment
	// to the principal also specified by the ProjectRoleAssignment. If the
	// specified Project or principal does not exist, implementations must return
	// a *meta.ErrNotFound error.
	Grant(context.Context, ProjectRoleAssignment) error

	// List returns a ProjectRoleAssignmentList, with its Items
	// (ProjectRoleAssignments) ordered by projectID, principal type, principalID,
	// and role. Criteria for which ProjectRoleAssignments should be retrieved can
	// be specified using the ProjectRoleAssignmentsSelector parameter.
	List(
		context.Context,
		ProjectRoleAssignmentsSelector,
		meta.ListOptions,
	) (ProjectRoleAssignmentList, error)

	// Revoke revokes the project-level Role specified by the
	// ProjectRoleAssignment for the principal also specified by the
	// ProjectRoleAssignment. If the specified principal does not exist,
	// implementations must return a *meta.ErrNotFound error.
	Revoke(context.Context, ProjectRoleAssignment) error
}

ProjectRoleAssignmentsService is the specialized interface for managing ProjectRoleAssignments. It's decoupled from underlying technology choices (e.g. data store, message bus, etc.) to keep business logic reusable and consistent while the underlying tech stack remains free to change.

func NewProjectRoleAssignmentsService

func NewProjectRoleAssignmentsService(
	authorize libAuthz.AuthorizeFn,
	projectAuthorize ProjectAuthorizeFn,
	projectsStore ProjectsStore,
	usersStore authn.UsersStore,
	serviceAccountsStore authn.ServiceAccountsStore,
	projectRoleAssignmentsStore ProjectRoleAssignmentsStore,
) ProjectRoleAssignmentsService

NewProjectRoleAssignmentsService returns a specialized interface for managing project-level RoleAssignments.

type ProjectRoleAssignmentsStore

type ProjectRoleAssignmentsStore interface {
	// Grant the project-level Role specified by the ProjectRoleAssignment to the
	// principal specified by the ProjectRoleAssignment.
	Grant(context.Context, ProjectRoleAssignment) error
	// List returns a ProjectRoleAssignmentsList, with its Items
	// (ProjectRoleAssignments) ordered by projectID, principal type, principalID,
	// and role. Criteria for which RoleAssignments should be retrieved can be
	// specified using the RoleAssignmentsSelector parameter.
	List(
		context.Context,
		ProjectRoleAssignmentsSelector,
		meta.ListOptions,
	) (ProjectRoleAssignmentList, error)
	// Revoke the Project specified by the ProjectRoleAssignment for the principal
	// specified by the ProjectRoleAssignment.
	Revoke(context.Context, ProjectRoleAssignment) error
	// RevokeByProjectID revokes all ProjectRoleAssignments for the specified
	// Project.
	RevokeByProjectID(ctx context.Context, projectID string) error
	// Exists returns a bool indicating whether the specified
	// ProjectRoleAssignment exists within the store. Implementations MUST also
	// return true if a ProjectRoleAssignment exists in the store that logically
	// "overlaps" the specified ProjectRoleAssignment. For instance, when seeking
	// to determine whether a ProjectRoleAssignment exists that endows some
	// principal P with Role X for Project Y, and such a ProjectRoleAssignment
	// does not exist, but one does that endows that principal P with Role X
	// having GLOBAL PROJECT SCOPE (*), then true MUST be returned.
	// Implementations MUST also return an error if and only if anything goes
	// wrong. i.e. Errors are never used to communicate that the specified
	// ProjectRoleAssignment does not exist in the store. They are only used to
	// convey an actual failure.
	Exists(context.Context, ProjectRoleAssignment) (bool, error)
}

ProjectRoleAssignmentsStore is an interface for components that implement ProjectRoleAssignment persistence concerns.

type ProjectSpec

type ProjectSpec struct {
	// EventSubscription defines a set of trigger conditions under which a new
	// Worker should be created.
	EventSubscriptions []EventSubscription `json:"eventSubscriptions,omitempty" bson:"eventSubscriptions,omitempty"` // nolint: lll
	// WorkerTemplate is a prototypical WorkerSpec.
	WorkerTemplate WorkerSpec `json:"workerTemplate" bson:"workerTemplate"`
}

ProjectSpec is the technical component of a Project. It pairs EventSubscriptions with a prototypical WorkerSpec that is used as a template for creating new Workers.

type ProjectsService

type ProjectsService interface {
	// Create creates a new Project. If a Project with the specified identifier
	// already exists, implementations MUST return a *meta.ErrConflict error.
	// Implementations may assume the Project passed to this function has been
	// pre-validated.
	Create(context.Context, Project) (Project, error)
	// List returns a ProjectList, with its Items (Projects) ordered
	// alphabetically by Project ID.
	List(context.Context, meta.ListOptions) (ProjectList, error)
	// Get retrieves a single Project specified by its identifier. If the
	// specified Project does not exist, implementations MUST return a
	// *meta.ErrNotFound error.
	Get(context.Context, string) (Project, error)
	// Update updates an existing Project. If the specified Project does not
	// exist, implementations MUST return a *meta.ErrNotFound error.
	// Implementations may assume the Project passed to this function has been
	// pre-validated.
	Update(context.Context, Project) error
	// Delete deletes a single Project specified by its identifier. If the
	// specified Project does not exist, implementations MUST return a
	// *meta.ErrNotFound error.
	Delete(context.Context, string) error
}

ProjectsService is the specialized interface for managing Projects. It's decoupled from underlying technology choices (e.g. data store, message bus, etc.) to keep business logic reusable and consistent while the underlying tech stack remains free to change.

func NewProjectsService

func NewProjectsService(
	authorizeFn libAuthz.AuthorizeFn,
	projectAuthorize ProjectAuthorizeFn,
	projectsStore ProjectsStore,
	eventsStore EventsStore,
	logsStore CoolLogsStore,
	projectRoleAssignmentsStore ProjectRoleAssignmentsStore,
	substrate Substrate,
) ProjectsService

NewProjectsService returns a specialized interface for managing Projects.

type ProjectsStore

type ProjectsStore interface {
	// Create stores the provided Project. Implementations MUST return a
	// *meta.ErrConflict error if a Project having the indicated identifier
	// already exists.
	Create(context.Context, Project) error
	// List returns a ProjectList, with its Items (Projects) ordered
	// alphabetically by Project ID.
	List(
		context.Context,
		meta.ListOptions,
	) (ProjectList, error)
	ListSubscribers(
		ctx context.Context,
		event Event,
	) (ProjectList, error)
	// Get returns a Project having the indicated ID. If no such Project exists,
	// implementations MUST return a *meta.ErrNotFound error.
	Get(context.Context, string) (Project, error)
	// Update updates the provided Project in storage, presuming that Project
	// already exists in storage. If no Project having the indicated ID already
	// exists, implementations MUST return a *meta.ErrNotFound error.
	// Implementations MUST apply updates ONLY to the Description and Spec fields,
	// as only these fields are intended to be mutable. Implementations MUST
	// ignore changes to all other fields when updating.
	Update(context.Context, Project) error
	// Delete deletes the specified Project. If no Project having the given
	// identifier is found, implementations MUST return a *meta.ErrNotFound error.
	Delete(context.Context, string) error
}

ProjectsStore is an interface for components that implement Project persistence concerns.

type Qualifiers

type Qualifiers map[string]string

func (Qualifiers) MarshalBSONValue

func (q Qualifiers) MarshalBSONValue() (bsontype.Type, []byte, error)

type Secret

type Secret struct {
	// Key is a key by which the secret can referred.
	Key string `json:"key,omitempty"`
	// Value is the sensitive information. This is a write-only field.
	Value string `json:"value,omitempty"`
}

Secret represents Project-level sensitive information.

func (Secret) MarshalJSON

func (s Secret) MarshalJSON() ([]byte, error)

MarshalJSON amends Secret instances with type metadata.

type SecretList

type SecretList struct {
	// ListMeta contains list metadata.
	meta.ListMeta `json:"metadata"`
	// Items is a slice of Secrets.
	Items []Secret `json:"items,omitempty"`
}

SecretList is an ordered and pageable list of Secrets.

func (SecretList) Len

func (s SecretList) Len() int

Len returns the cardinality of the underlying Items field.

func (SecretList) Less

func (s SecretList) Less(i, j int) bool

Less returns true when Secret i's Key field is less than Secret j's Key field in the underlying Items field (when compared lexically).

func (SecretList) MarshalJSON

func (s SecretList) MarshalJSON() ([]byte, error)

MarshalJSON amends SecretList instances with type metadata.

func (SecretList) Swap

func (s SecretList) Swap(i, j int)

Swap swaps Secret i and Secret j in the underlying Items field.

type SecretsService

type SecretsService interface {
	// List returns a SecretList whose Items (Secrets) contain Keys only and
	// not Values (all Value fields are empty). i.e. Once a secret is set, end
	// clients are unable to retrieve values.
	List(
		ctx context.Context,
		projectID string,
		opts meta.ListOptions,
	) (SecretList, error)
	// Set sets the value of a new Secret or updates the value of an existing
	// Secret. If the specified Project does not exist, implementations MUST
	// return a *meta.ErrNotFound error. If the specified Key does not exist, it
	// is created. If the specified Key does exist, its corresponding Value is
	// overwritten.
	Set(
		ctx context.Context,
		projectID string,
		secret Secret,
	) error
	// Unset clears the value of an existing Secret. If the specified Project does
	// not exist, implementations MUST return a *meta.ErrNotFound error. If the
	// specified Key does not exist, no error is returned.
	Unset(ctx context.Context, projectID string, key string) error
}

SecretsService is the specialized interface for managing Secrets. It's decoupled from underlying technology choices (e.g. data store, message bus, etc.) to keep business logic reusable and consistent while the underlying tech stack remains free to change.

func NewSecretsService

func NewSecretsService(
	authorizeFn libAuthz.AuthorizeFn,
	projectAuthorize ProjectAuthorizeFn,
	projectsStore ProjectsStore,
	secretsStore SecretsStore,
) SecretsService

NewSecretsService returns a specialized interface for managing Secrets.

type SecretsStore

type SecretsStore interface {
	// List returns a SecretList, with its Items (Secrets) ordered lexically by
	// Key.
	List(ctx context.Context,
		project Project,
		opts meta.ListOptions,
	) (SecretList, error)
	// Set adds or updates the provided Secret associated with the specified
	// Project.
	Set(ctx context.Context, project Project, secret Secret) error
	// Unset clears (deletes) the Secret (identified by its Key) associated with
	// the specified Project.
	Unset(ctx context.Context, project Project, key string) error
}

SecretsStore is an interface for components that implement Secret persistence concerns.

type SourceState

type SourceState struct {
	// State is a map of arbitrary and opaque key/value pairs that the source of
	// an Event (e.g. the gateway that created it) can use to store
	// source-specific state.
	State map[string]string `json:"state,omitempty" bson:"state,omitempty"`
}

SourceState encapsulates opaque, source-specific (e.g. gateway-specific) state.

type Substrate

type Substrate interface {
	// CountRunningWorkers returns a count of Workers currently executing on the
	// substrate.
	CountRunningWorkers(context.Context) (SubstrateWorkerCount, error)
	// CountRunningJobs returns a count of Jobs currently executing on the
	// substrate.
	CountRunningJobs(context.Context) (SubstrateJobCount, error)

	// CreateProject prepares the substrate to host Project workloads. The
	// provided Project argument may be amended with substrate-specific details
	// and returned, so this function should be called prior to a Project being
	// initially persisted so that substrate-specific details will be included.
	CreateProject(context.Context, Project) (Project, error)
	// DeleteProject removes all Project-related resources from the substrate.
	DeleteProject(context.Context, Project) error

	// ScheduleWorker prepares the substrate for the Event's worker and schedules
	// the Worker for async / eventual execution.
	ScheduleWorker(context.Context, Project, Event) error
	// StartWorker starts an Event's Worker on the substrate.
	StartWorker(context.Context, Project, Event) error

	// StoreJobEnvironment securely stores Job environment variables where they
	// are accessible to other substrate operations. This obviates the need to
	// store these potential secrets in the database.
	StoreJobEnvironment(
		ctx context.Context,
		project Project,
		eventID string,
		jobName string,
		jobSpec JobSpec,
	) error
	// ScheduleJob prepares the substrate for a Job and schedules the Job for
	// async / eventual execution.
	ScheduleJob(
		ctx context.Context,
		project Project,
		event Event,
		jobName string,
	) error
	// StartJob starts a Job on the substrate.
	StartJob(
		ctx context.Context,
		project Project,
		event Event,
		jobName string,
	) error

	// DeleteJob deletes all substrate resources pertaining to the specified Job.
	DeleteJob(
		ctx context.Context,
		project Project,
		event Event,
		jobName string,
	) error

	// DeleteWorkerAndJobs deletes all substrate resources pertaining to the
	// specified Event's Worker and Jobs.
	DeleteWorkerAndJobs(context.Context, Project, Event) error
}

Substrate is an interface for components that permit services to coordinate with Brigade's underlying workload execution substrate, i.e. Kubernetes.

type SubstrateJobCount

type SubstrateJobCount struct {
	// Count is the cardinality of Jobs currently executing on the substrate.
	Count int `json:"count"`
}

SubstrateJobCount represents a count of Workers currently executing on the substrate.

func (SubstrateJobCount) MarshalJSON

func (s SubstrateJobCount) MarshalJSON() ([]byte, error)

MarshalJSON amends SubstrateJobCount instances with type metadata.

type SubstrateService

type SubstrateService interface {
	// CountRunningWorkers returns a count of Workers currently executing on the
	// substrate.
	CountRunningWorkers(context.Context) (SubstrateWorkerCount, error)
	// CountRunningJobs returns a count of Jobs currently executing on the
	// substrate.
	CountRunningJobs(context.Context) (SubstrateJobCount, error)
}

SubstrateService is the specialized interface for monitoring the state of the substrate.

func NewSubstrateService

func NewSubstrateService(
	authorizeFn libAuthz.AuthorizeFn,
	substrate Substrate,
) SubstrateService

NewSubstrateService returns a specialized interface for managing Projects.

type SubstrateWorkerCount

type SubstrateWorkerCount struct {
	// Count is the cardinality of Workers currently executing on the substrate.
	Count int `json:"count"`
}

SubstrateWorkerCount represents a count of Workers currently executing on the substrate.

func (SubstrateWorkerCount) MarshalJSON

func (s SubstrateWorkerCount) MarshalJSON() ([]byte, error)

MarshalJSON amends SubstrateWorkerCount instances with type metadata.

type Worker

type Worker struct {
	// Spec is the technical blueprint for the Worker.
	Spec WorkerSpec `json:"spec" bson:"spec"`
	// Status contains details of the Worker's current state.
	Status WorkerStatus `json:"status" bson:"status"`
	// Token is an API token that grants a Worker permission to create new Jobs
	// only for the Event to which it belongs.
	Token string `json:"-" bson:"-"`
	// HashedToken is a secure hash of the Token field.
	HashedToken string `json:"-" bson:"hashedToken"`
	// Jobs contains details of all Jobs spawned by the Worker during handling of
	// the Event.
	Jobs []Job `json:"jobs,omitempty" bson:"jobs"`
}

Worker represents a component that orchestrates handling of a single Event.

func (*Worker) Job

func (w *Worker) Job(jobName string) (Job, bool)

Job retrieves a Job by name. It returns a boolean indicating whether the returned Job is the one requested (true) or a zero value (false) because no Job with the specified name belongs to this Worker.

type WorkerPhase

type WorkerPhase string

WorkerPhase represents where a Worker is within its lifecycle.

const (
	// WorkerPhaseAborted represents the state wherein a Worker was forcefully
	// stopped during execution.
	WorkerPhaseAborted WorkerPhase = "ABORTED"
	// WorkerPhaseCanceled represents the state wherein a pending Worker was
	// canceled prior to execution.
	WorkerPhaseCanceled WorkerPhase = "CANCELED"
	// WorkerPhaseFailed represents the state wherein a Worker has run to
	// completion but experienced errors.
	WorkerPhaseFailed WorkerPhase = "FAILED"
	// WorkerPhasePending represents the state wherein a Worker is awaiting
	// execution.
	WorkerPhasePending WorkerPhase = "PENDING"
	// WorkerPhaseRunning represents the state wherein a Worker is currently
	// being executed.
	WorkerPhaseRunning WorkerPhase = "RUNNING"
	// WorkerPhaseSchedulingFailed represents the state wherein a Worker was not
	// scheduled due to some unexpected and unrecoverable error encountered by the
	// scheduler.
	WorkerPhaseSchedulingFailed WorkerPhase = "SCHEDULING_FAILED"
	// WorkerPhaseStarting represents the state wherein a Worker is starting on
	// the substrate but isn't running yet.
	WorkerPhaseStarting WorkerPhase = "STARTING"
	// WorkerPhaseSucceeded represents the state where a Worker has run to
	// completion without error.
	WorkerPhaseSucceeded WorkerPhase = "SUCCEEDED"
	// WorkerPhaseTimedOut represents the state wherein a Worker has has not
	// completed within a designated timeframe.
	WorkerPhaseTimedOut WorkerPhase = "TIMED_OUT"
	// WorkerPhaseUnknown represents the state wherein a Worker's state is
	// unknown. Note that this is possible if and only if the underlying Worker
	// execution substrate (Kubernetes), for some unanticipated, reason does not
	// know the Worker's (Pod's) state.
	WorkerPhaseUnknown WorkerPhase = "UNKNOWN"
)

func WorkerPhasesAll

func WorkerPhasesAll() []WorkerPhase

WorkerPhasesAll returns a slice of WorkerPhases containing ALL possible phases. Note that instead of utilizing a package-level slice, this a function returns ad-hoc copies of the slice in order to preclude the possibility of this important collection being modified at runtime.

func (WorkerPhase) IsTerminal

func (w WorkerPhase) IsTerminal() bool

IsTerminal returns a bool indicating whether the WorkerPhase is terminal.

type WorkerSpec

type WorkerSpec struct {
	// Container specifies the details of an OCI container that forms the
	// cornerstone of the Worker.
	Container *ContainerSpec `json:"container,omitempty" bson:"container,omitempty"` // nolint: lll
	// UseWorkspace indicates whether the Worker and/or any Jobs it may spawn
	// requires access to a shared workspace. When false, no such workspace is
	// provisioned prior to Worker creation. This is a generally useful feature,
	// but by opting out of it (or rather, not opting-in), Job results can be made
	// cacheable and Jobs resumable/retriable-- something which cannot be done
	// otherwise since managing the state of the shared volume would require a
	// layered file system that we currently do not have.
	UseWorkspace bool `json:"useWorkspace" bson:"useWorkspace"`
	// WorkspaceSize specifies the size of a volume that will be provisioned as
	// a shared workspace for the Worker and any Jobs it spawns.
	// The value can be expressed in bytes (as a plain integer) or as a
	// fixed-point integer using one of these suffixes: E, P, T, G, M, K.
	// Power-of-two equivalents may also be used: Ei, Pi, Ti, Gi, Mi, Ki.
	WorkspaceSize string `json:"workspaceSize,omitempty" bson:"workspaceSize,omitempty"` // nolint: lll
	// Git contains git-specific Worker details.
	Git *GitConfig `json:"git,omitempty"`
	// Kubernetes contains Kubernetes-specific Worker details.
	Kubernetes *KubernetesConfig `json:"kubernetes,omitempty" bson:"kubernetes,omitempty"` // nolint: lll
	// JobPolicies specifies policies for any Jobs spawned by the Worker.
	JobPolicies *JobPolicies `json:"jobPolicies,omitempty" bson:"jobPolicies,omitempty"` // nolint: lll
	// LogLevel specifies the desired granularity of Worker log output.
	LogLevel LogLevel `json:"logLevel,omitempty" bson:"logLevel,omitempty"`
	// ConfigFilesDirectory specifies a directory within the Worker's workspace
	// where any relevant configuration files (e.g. brigade.json, brigade.js,
	// etc.) can be located.
	ConfigFilesDirectory string `json:"configFilesDirectory,omitempty" bson:"configFilesDirectory,omitempty"` // nolint: lll
	// DefaultConfigFiles is a map of configuration file names to configuration
	// file content. This is useful for Workers that do not integrate with any
	// source control system and would like to embed configuration (e.g.
	// brigade.json) or scripts (e.g. brigade.js) directly within the WorkerSpec.
	DefaultConfigFiles map[string]string `json:"defaultConfigFiles,omitempty" bson:"defaultConfigFiles,omitempty"` // nolint: lll
}

WorkerSpec is the technical blueprint for a Worker.

type WorkerStatus

type WorkerStatus struct {
	// Started indicates the time the Worker began execution. It will be nil for
	// a Worker that is not yet executing.
	Started *time.Time `json:"started,omitempty" bson:"started,omitempty"`
	// Ended indicates the time the Worker concluded execution. It will be nil
	// for a Worker that is not done executing (or hasn't started).
	Ended *time.Time `json:"ended,omitempty" bson:"ended,omitempty"`
	// Phase indicates where the Worker is in its lifecycle.
	Phase WorkerPhase `json:"phase,omitempty" bson:"phase,omitempty"`
}

WorkerStatus represents the status of a Worker.

type WorkersService

type WorkersService interface {
	// Start starts the indicated Event's Worker on Brigade's workload
	// execution substrate. If the specified Event does not exist, implementations
	// MUST return a *meta.ErrNotFound.
	Start(ctx context.Context, eventID string) error
	// GetStatus returns an Event's Worker's status. If the specified Event does
	// not exist, implementations MUST return a *meta.ErrNotFound.
	GetStatus(
		ctx context.Context,
		eventID string,
	) (WorkerStatus, error)
	// WatchStatus returns a channel over which an Event's Worker's status is
	// streamed. The channel receives a new WorkerStatus every time there is any
	// change in that status. If the specified Event does not exist,
	// implementations MUST return a *meta.ErrNotFound.
	WatchStatus(
		ctx context.Context,
		eventID string,
	) (<-chan WorkerStatus, error)
	// UpdateStatus updates the status of an Event's Worker. If the specified
	// Event does not exist, implementations MUST return a *meta.ErrNotFound.
	UpdateStatus(
		ctx context.Context,
		eventID string,
		status WorkerStatus,
	) error
	// Cleanup removes Worker-related resources from the substrate, presumably
	// upon completion, without deleting the Worker from the data store.
	Cleanup(ctx context.Context, eventID string) error
}

WorkersService is the specialized interface for managing Workers. It's decoupled from underlying technology choices (e.g. data store, message bus, etc.) to keep business logic reusable and consistent while the underlying tech stack remains free to change.

func NewWorkersService

func NewWorkersService(
	authorizeFn libAuthz.AuthorizeFn,
	projectsStore ProjectsStore,
	eventsStore EventsStore,
	workersStore WorkersStore,
	substrate Substrate,
) WorkersService

NewWorkersService returns a specialized interface for managing Workers.

type WorkersStore

type WorkersStore interface {
	UpdateStatus(
		ctx context.Context,
		eventID string,
		status WorkerStatus,
	) error
}

WorkersStore is an interface for components that implement Worker persistence concerns.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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