Documentation ¶
Index ¶
- Constants
- func ContextWithPrincipal(ctx context.Context, principal interface{}) context.Context
- func ContextWithSessionID(ctx context.Context, sessionID string) context.Context
- func PrincipalFromContext(ctx context.Context) interface{}
- func SessionIDFromContext(ctx context.Context) string
- type AuthorizeFn
- type Authorizer
- type CancelManyEventsResult
- type ContainerSpec
- type CoolLogsStore
- type DeleteManyEventsResult
- type Event
- type EventList
- type EventSubscription
- type EventSummary
- type EventsSelector
- type EventsService
- type EventsStore
- type GitConfig
- type GitDetails
- type ImagePullPolicy
- type Job
- type JobContainerSpec
- type JobHost
- type JobPhase
- type JobPolicies
- type JobSpec
- type JobStatus
- type JobsService
- type JobsStore
- type KubernetesConfig
- type KubernetesDetails
- type LogEntry
- type LogLevel
- type LogStreamOptions
- type LogsSelector
- type LogsService
- type LogsStore
- type PrincipalReference
- type PrincipalType
- type Project
- type ProjectAuthorizeFn
- type ProjectAuthorizer
- type ProjectList
- type ProjectRoleAssignment
- type ProjectRoleAssignmentList
- type ProjectRoleAssignmentsSelector
- type ProjectRoleAssignmentsService
- type ProjectRoleAssignmentsStore
- type ProjectSpec
- type ProjectsService
- type ProjectsStore
- type Qualifiers
- type Role
- type RoleAssignment
- type RoleAssignmentList
- type RoleAssignmentsSelector
- type RoleAssignmentsService
- type RoleAssignmentsStore
- type Secret
- type SecretList
- type SecretsService
- type SecretsStore
- type ServiceAccount
- type ServiceAccountList
- type ServiceAccountsService
- type ServiceAccountsStore
- type Session
- type SessionsService
- type SessionsServiceConfig
- type SessionsStore
- type SourceState
- type Substrate
- type SubstrateJobCount
- type SubstrateService
- type SubstrateWorkerCount
- type ThirdPartyAuthDetails
- type ThirdPartyAuthHelper
- type ThirdPartyAuthOptions
- type ThirdPartyAuthStrategy
- type ThirdPartyIdentity
- type Token
- type User
- type UserList
- type UsersService
- type UsersServiceConfig
- type UsersStore
- type Worker
- type WorkerPhase
- type WorkerSpec
- type WorkerStatus
- type WorkersService
- type WorkersStore
Constants ¶
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" )
const ( // ProjectRoleAssignmentKind represents the canonical ProjectRoleAssignment // kind string ProjectRoleAssignmentKind = "ProjectRoleAssignment" // ProjectRoleAssignmentListKind represents the canonical // ProjectRoleAssignmentList kind string ProjectRoleAssignmentListKind = "ProjectRoleAssignmentList" )
const ( // RoleAssignmentKind represents the canonical RoleAssignment kind string RoleAssignmentKind = "RoleAssignment" // RoleAssignmentListKind represents the canonical RoleAssignmentList kind // string RoleAssignmentListKind = "RoleAssignmentList" )
const JobKind = "Job"
JobKind represents the canonical Job kind string
const ProjectKind = "Project"
ProjectKind represents the canonical Project kind string
const ProjectRoleScopeGlobal = "*"
ProjectRoleScopeGlobal represents an unbounded project scope.
const RoleScopeGlobal = "*"
RoleScopeGlobal represents an unbounded scope.
const ServiceAccountKind = "ServiceAccount"
ServiceAccountKind represents the canonical Service Account kind string
const SessionKind = "Session"
SessionKind represents the canonical Session kind string
const UserKind = "User"
UserKind represents the canonical User kind string
Variables ¶
This section is empty.
Functions ¶
func ContextWithPrincipal ¶
ContextWithPrincipal returns a context.Context that has been augmented with the provided principal.
func ContextWithSessionID ¶
ContextWithSessionID returns a context.Context that has been augmented with the provided Session identifier.
func PrincipalFromContext ¶
PrincipalFromContext extracts a principal from the provided context.Context and returns it.
func SessionIDFromContext ¶
SessionIDFromContext extracts a Session identifier from the provided context.Context and returns it.
Types ¶
type AuthorizeFn ¶
AuthorizeFn 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 with the specified scope. Implementations MUST return a *meta.ErrAuthorization error if the principal is not authorized.
type Authorizer ¶
type Authorizer interface { // Authorize retrieves a principal from the provided Context and asserts that // it has the specified Role with the specified scope. If it does not, // implementations MUST return a *meta.ErrAuthorization error. Authorize(ctx context.Context, roles Role, scope string) error }
Authorizer is the public interface for the component returned by the NewAuthorizer function.
func NewAuthorizer ¶
func NewAuthorizer(roleAssignmentsStore RoleAssignmentsStore) Authorizer
NewAuthorizer returns a component that can authorize a request.
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"` // Summary is a counterpart to Payload. If Payload is free-form Worker input, // then Summary is free-form Worker output. It can optionally be set by a // Worker to provide a summary of the work completed by the Worker and its // Jobs. Summary string `json:"summary,omitempty" bson:"summary,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 ¶
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 ¶
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 EventSummary ¶
type EventSummary struct { // Text is the Event summary as (optionally) provided by a Worker. Text string `json:"text,omitempty"` }
EventSummary encapsulates an opaque, Worker-specific summary of an Event.
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 // UpdateSummary updates the opaque, Worker-specific summary of work performed // by the Worker and its Jobs. UpdateSummary(context.Context, string, EventSummary) 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 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 // UpdateSummary updates the opaque, Worker-specific Event summary. UpdateSummary(context.Context, string, EventSummary) 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) // DeleteByProjectID unconditionally deletes all Events associated with the // specified project. DeleteByProjectID(context.Context, string) 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, this field is interpreted // as a reference to the repository's default branch. 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 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, this field is interpreted // as a reference to the repository's default branch. 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"` // Created indicates the time at which a Job was created. Created *time.Time `json:"created,omitempty"` // 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 ¶
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 ¶
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 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 ¶
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 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 PrincipalReference ¶
type PrincipalReference struct { // Type qualifies what kind of principal is referenced by the ID field-- for // instance, a User or a ServiceAccount. Type PrincipalType `json:"type,omitempty"` // ID references a principal. The Type qualifies what type of principal that // is-- for instance, a User or a ServiceAccount. ID string `json:"id,omitempty"` }
PrincipalReference is a reference to any sort of security principal (human user, service account, etc.)
type PrincipalType ¶
type PrincipalType string
PrincipalType is a type whose values can be used to disambiguate one type of principal from another. For instance, when assigning a Role to a principal via a RoleAssignment, a PrincipalType field is used to indicate whether the value of the PrincipalID field reflects a User ID or a ServiceAccount ID.
const ( // PrincipalTypeServiceAccount represents a principal that is a // ServiceAccount. PrincipalTypeServiceAccount PrincipalType = "SERVICE_ACCOUNT" // PrincipalTypeUser represents a principal that is a User. PrincipalTypeUser PrincipalType = "USER" )
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 ¶
MarshalJSON amends Project instances with type metadata.
type ProjectAuthorizeFn ¶
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 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) Contains ¶
func (p ProjectList) Contains(project Project) bool
Contains returns a boolean value indicating whether the ProjectList contains the provided Project
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 Role `json:"role" bson:"role"` // Principal specifies the principal to whom the Role is assigned. Principal 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.
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 *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 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 AuthorizeFn, projectAuthorize ProjectAuthorizeFn, projectsStore ProjectsStore, usersStore UsersStore, serviceAccountsStore 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 // RevokeByPrincipal revokes all project roles for the principal specified by // the PrincipalReference. RevokeByPrincipal(context.Context, PrincipalReference) 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 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 ¶
func (Qualifiers) MarshalBSONValue ¶
func (q Qualifiers) MarshalBSONValue() (bsontype.Type, []byte, error)
type Role ¶
type Role string
Role is a type whose value maps to a well-defined Brigade Role.
const ( // RoleProjectAdmin represents a project-level Role that enables a principal // to manage a Project. RoleProjectAdmin Role = "PROJECT_ADMIN" // RoleProjectDeveloper represents a project-level Role that enables a // principal to update a Project. RoleProjectDeveloper Role = "PROJECT_DEVELOPER" // RoleProjectUser represents a project-level Role that enables a principal to // create and manage Events for a Project. RoleProjectUser Role = "PROJECT_USER" )
const ( // RoleAdmin represents a system-level Role that enables principals to manage // Users, ServiceAccounts, and system-level permissions for Users and // ServiceAccounts. RoleAdmin Role = "ADMIN" // RoleEventCreator represents a system-level Role that enables principals to // create Events for all Projects. RoleEventCreator Role = "EVENT_CREATOR" // RoleProjectCreator represents a system-level Role that enables principals // to create new Projects. RoleProjectCreator Role = "PROJECT_CREATOR" // RoleReader represents a system-level Role that enables global read access. RoleReader Role = "READER" )
const ( // 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 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 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 Role = "WORKER" )
type RoleAssignment ¶
type RoleAssignment struct { // Role assigns a Role to the specified principal. Role Role `json:"role" bson:"role"` // Principal specifies the principal to whom the Role is assigned. Principal PrincipalReference `json:"principal" bson:"principal"` // Scope qualifies the scope of the Role. The value is opaque and has meaning // only in relation to a specific Role. Scope string `json:"scope,omitempty" bson:"scope,omitempty"` }
RoleAssignment represents the assignment of a Role to a principal such as a User or ServiceAccount.
func (RoleAssignment) MarshalJSON ¶
func (r RoleAssignment) MarshalJSON() ([]byte, error)
MarshalJSON amends RoleAssignment instances with type metadata.
type RoleAssignmentList ¶
type RoleAssignmentList struct { // ListMeta contains list metadata. meta.ListMeta `json:"metadata"` // Items is a slice of RoleAssignments. Items []RoleAssignment `json:"items,omitempty"` }
RoleAssignmentList is an ordered and pageable list of system-level RoleAssignments.
func (RoleAssignmentList) MarshalJSON ¶
func (r RoleAssignmentList) MarshalJSON() ([]byte, error)
MarshalJSON amends RoleAssignmentList instances with type metadata.
type RoleAssignmentsSelector ¶
type RoleAssignmentsSelector struct { // Principal specifies that only RoleAssignments for the specified principal // should be selected. Principal *PrincipalReference // Role specifies that only RoleAssignments for the specified Role should be // selected. Role Role }
RoleAssignmentsSelector represents useful filter criteria when selecting multiple RoleAssignments for API group operations like list.
type RoleAssignmentsService ¶
type RoleAssignmentsService interface { // Grant grants the Role specified by the RoleAssignment to the principal also // specified by the RoleAssignment. If the specified principal does not exist, // implementations must return a *meta.ErrNotFound error. Grant(ctx context.Context, roleAssignment RoleAssignment) error // List returns a RoleAssignmentsList, with its Items (RoleAssignments) // ordered by principal type, principalID, role, and scope. Criteria for which // RoleAssignments should be retrieved can be specified using the // RoleAssignmentsSelector parameter. List( context.Context, RoleAssignmentsSelector, meta.ListOptions, ) (RoleAssignmentList, error) // Revoke revokes the Role specified by the RoleAssignment for the principal // also specified by the RoleAssignment. If the specified principal does not // exist, implementations must return a *meta.ErrNotFound error. Revoke(ctx context.Context, roleAssignment RoleAssignment) error }
RoleAssignmentsService is the specialized interface for managing RoleAssignments. 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 NewRoleAssignmentsService ¶
func NewRoleAssignmentsService( authorizeFn AuthorizeFn, usersStore UsersStore, serviceAccountsStore ServiceAccountsStore, roleAssignmentsStore RoleAssignmentsStore, ) RoleAssignmentsService
NewRoleAssignmentsService returns a specialized interface for managing RoleAssignments.
type RoleAssignmentsStore ¶
type RoleAssignmentsStore interface { // Grant the role specified by the RoleAssignment to the principal specified // by the RoleAssignment. Grant(context.Context, RoleAssignment) error // List returns a RoleAssignmentsList, with its Items (system-level // RoleAssignments) ordered by principal type, principalID, role name, and // scope. Criteria for which RoleAssignments should be retrieved can be // specified using the RoleAssignmentsSelector parameter. List( context.Context, RoleAssignmentsSelector, meta.ListOptions, ) (RoleAssignmentList, error) // Revoke the role specified by the RoleAssignment for the principal specified // by the RoleAssignment. Revoke(context.Context, RoleAssignment) error // RevokeByPrincipal revokes all roles for the principal specified by the // PrincipalReference. RevokeByPrincipal(context.Context, PrincipalReference) error // Exists returns a bool indicating whether the specified RoleAssignment // exists within the store. Implementations MUST also return true if a // RoleAssignment exists in the store that logically "overlaps" the specified // RoleAssignment. For instance, when seeking to determine whether a // RoleAssignment exists that endows some principal P with Role X having scope // Y, and such a RoleAssignment does not exist, but one does that endows that // principal P with Role X having GLOBAL 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 // RoleAssignment does not exist in the store. They are only used to convey an // actual failure. Exists(context.Context, RoleAssignment) (bool, error) }
RoleAssignmentsStore is an interface for components that implement RoleAssignment persistence concerns.
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 ¶
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 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 ServiceAccount ¶
type ServiceAccount struct { // ObjectMeta encapsulates ServiceAccount metadata. meta.ObjectMeta `json:"metadata" bson:",inline"` // Description is a natural language description of the ServiceAccount's // purpose. Description string `json:"description" bson:"description"` // HashedToken is a secure, one-way hash of the ServiceAccount's token. HashedToken string `json:"-" bson:"hashedToken"` // Locked indicates when the ServiceAccount has been locked out of the system // by an administrator. If this field's value is nil, the ServiceAccount is // not locked. Locked *time.Time `json:"locked,omitempty" bson:"locked"` }
ServiceAccount represents a non-human Brigade user, such as an Event gateway.
func (ServiceAccount) MarshalJSON ¶
func (s ServiceAccount) MarshalJSON() ([]byte, error)
MarshalJSON amends ServiceAccount instances with type metadata.
type ServiceAccountList ¶
type ServiceAccountList struct { // ListMeta contains list metadata. meta.ListMeta `json:"metadata"` // Items is a slice of ServiceAccounts. Items []ServiceAccount `json:"items,omitempty"` }
ServiceAccountList is an ordered and pageable list of ServiceAccounts.
func (ServiceAccountList) MarshalJSON ¶
func (s ServiceAccountList) MarshalJSON() ([]byte, error)
MarshalJSON amends ServiceAccountList instances with type metadata.
type ServiceAccountsService ¶
type ServiceAccountsService interface { // Create creates a new ServiceAccount. If a ServiceAccount having the same ID // already exists, implementations MUST return a *meta.ErrConflict error. Create(context.Context, ServiceAccount) (Token, error) // List retrieves a ServiceAccountList. List(context.Context, meta.ListOptions) (ServiceAccountList, error) // Get retrieves a single ServiceAccount specified by its identifier. If the // specified ServiceAccount does not exist, implementations MUST return a // *meta.ErrNotFound error. Get(context.Context, string) (ServiceAccount, error) // GetByToken retrieves a single ServiceAccount specified by token. If no // such ServiceAccount exists, implementations MUST return a *meta.ErrNotFound // error. GetByToken(context.Context, string) (ServiceAccount, error) // Lock revokes system access for a single ServiceAccount specified by its // identifier. If the specified ServiceAccount does not exist, implementations // MUST return a *meta.ErrNotFound error. Lock(context.Context, string) error // Unlock restores system access for a single ServiceAccount (after presumably // having been revoked) specified by its identifier. It returns a new Token. // If the specified ServiceAccount does not exist, implementations MUST return // a *meta.ErrNotFound error. Unlock(context.Context, string) (Token, error) // Delete removes a single ServiceAccount specified by its identifier. Delete(context.Context, string) error }
ServiceAccountsService is the specialized interface for managing ServiceAccounts. It's decoupled from underlying technology choices (e.g. data store) to keep business logic reusable and consistent while the underlying tech stack remains free to change.
func NewServiceAccountsService ¶
func NewServiceAccountsService( authorizeFn AuthorizeFn, store ServiceAccountsStore, roleAssignmentsStore RoleAssignmentsStore, projectRoleAssignmentsStore ProjectRoleAssignmentsStore, ) ServiceAccountsService
NewServiceAccountsService returns a specialized interface for managing ServiceAccounts.
type ServiceAccountsStore ¶
type ServiceAccountsStore interface { // Create persists a new ServiceAccount in the underlying data store. If a // ServiceAccount having the same ID already exists, implementations MUST // return a *meta.ErrConflict error. Create(context.Context, ServiceAccount) error // List retrieves a ServiceAccountList from the underlying data store, with // its Items (ServiceAccounts) ordered by ID. List(context.Context, meta.ListOptions) (ServiceAccountList, error) // Get retrieves a single ServiceAccount from the underlying data store. If // the specified ServiceAccount does not exist, implementations MUST return // a *meta.ErrNotFound error. Get(context.Context, string) (ServiceAccount, error) // GetByHashedToken retrieves a single ServiceAccount having the provided // hashed token from the underlying data store. If no such ServiceAccount // exists, implementations MUST return a *meta.ErrNotFound error. GetByHashedToken(context.Context, string) (ServiceAccount, error) // Lock updates the specified ServiceAccount in the underlying data store to // reflect that it has been locked out of the system. If the specified // ServiceAccount does not exist, implementations MUST return a // *meta.ErrNotFound error. Lock(context.Context, string) error // Unlock updates the specified ServiceAccount in the underlying data store to // reflect that it's system access (after presumably having been revoked) has // been restored. A hashed token must be provided as a replacement for the // existing token. If the specified ServiceAccount does not exist, // implementations MUST return a *meta.ErrNotFound error. Unlock(ctx context.Context, id string, newHashedToken string) error // Delete deletes the specified ServiceAccount. If no ServiceAccount having // the given identifier is found, implementations MUST return a // *meta.ErrNotFound error. Delete(context.Context, string) error }
ServiceAccountsStore is an interface for components that implement ServiceAccount persistence concerns.
type Session ¶
type Session struct { // ObjectMeta encapsulates Session metadata. meta.ObjectMeta `json:"metadata" bson:",inline"` // Root indicates whether the Session belongs to the root user (true) or a // some discrete User. Root bool `json:"root" bson:"root"` // UserID, if set, identifies the discrete User to whom this Session belongs. UserID string `json:"userID" bson:"userID"` // HashedOAuth2State, if set, is a secure hash of the OAuth 2 "state" code // used in completing authentication via a third-party identity provider. HashedOAuth2State string `json:"-" bson:"hashedOAuth2State"` // HashedToken is a secure hash of the opaque bearer token associated with // this Session. HashedToken string `json:"-" bson:"hashedToken"` // Authenticated indicates the date/time at which authentication was completed // successfully. If the value of this field is nil, the Session is NOT // authenticated. Authenticated *time.Time `json:"authenticated" bson:"authenticated"` // Expires, if set, specified an expiry date/time for the Session and its // associated token. Expires *time.Time `json:"expires" bson:"expires"` // AuthSuccessURL indicates a URL to redirect the User to after successful // completion of a third-party authentication workflow. If not specified, a // default URL is used. AuthSuccessURL string `json:"authSuccessURL" bson:"authSuccessURL"` }
Session encapsulates details of a session belonging either to the root user or a discrete User that has authenticated (or is in the process of authenticating) via OpenID Connect or GitHub.
type SessionsService ¶
type SessionsService interface { // CreateRootSession creates a Session for the root user (if enabled by the // system administrator) and returns a Token with a short expiry period // (determined by a system administrator). If authentication as the root user // is not enabled, implementations MUST return a *meta.ErrNotSupported error. // If the specified username is not "root" or the specified password is // incorrect, implementations MUST return a *meta.ErrAuthentication error. CreateRootSession( ctx context.Context, username string, password string, ) (Token, error) // CreateUserSession creates a new User Session and initiates a third-party // authentication workflow (if enabled by the system administrator). It // returns ThirdPartyAuthDetails containing all information required to // continue the authentication process with the third-party identity provider. // If authentication using a third-party is not enabled, implementations MUST // return a *meta.ErrNotSupported error. CreateUserSession( context.Context, *ThirdPartyAuthOptions, ) (ThirdPartyAuthDetails, error) // Authenticate completes the final steps of the third-party authentication // workflow (if enabled by the system administrator) and returns a URL to // which the user may be redirected. It uses the provided state to identify an // as-yet anonymous Session (with an as-yet unactivated token). It // communicates with the third-party identity provider, exchanging the // provided code for user information. This information can be used to // correlate the as-yet anonymous Session to an existing User. If the User is // previously unknown to Brigade, implementations MUST seamlessly create one // (with no initial permissions) based on information provided by the identity // provider. Finally, the Session's token is activated. If authentication // using a third-party is not enabled, implementations MUST return a // *meta.ErrNotSupported error. Authenticate(ctx context.Context, state string, code string) (string, error) // GetByToken retrieves the Session having the provided token. If no such // Session is found or is found but is expired, implementations MUST return a // *meta.ErrAuthentication error. GetByToken(ctx context.Context, token string) (Session, error) // Delete deletes the specified Session. Delete(ctx context.Context, id string) error }
SessionsService is the specialized interface for managing Sessions. It's decoupled from underlying technology choices (e.g. data store) to keep business logic reusable and consistent while the underlying tech stack remains free to change.
func NewSessionsService ¶
func NewSessionsService( sessionsStore SessionsStore, usersStore UsersStore, roleAssignmentsStore RoleAssignmentsStore, thirdPartyAuthHelper ThirdPartyAuthHelper, config *SessionsServiceConfig, ) SessionsService
NewSessionsService returns a specialized interface for managing Sessions.
type SessionsServiceConfig ¶
type SessionsServiceConfig struct { // RootUserEnabled indicates whether the Session service should permit the // "root" user to authenticate using a password. RootUserEnabled bool // RootUserSessionTTL specifies the TTL for the root user session. This value // will be used to set the Expires field on the Session record for the root // user. RootUserSessionTTL time.Duration // RootUserPassword specifies the password that must be supplied by users // attempting to authenticate as the "root" user. This field is applicable // only when value of the RootUserEnabled field is true. RootUserPassword string // ThirdPartyAuthEnabled indicates whether authentication using a third-party // identity provider is supported by the Sessions service. ThirdPartyAuthEnabled bool // UserSessionTTL specifies the TTL for user sessions. This value will be // used to set the Expires field on the Session record for each user. UserSessionTTL time.Duration // AdminUserIDs enumerates users who should be granted system admin privileges // the first time they log in. AdminUserIDs []string }
SessionsServiceConfig encapsulates several configuration options for the Sessions service.
type SessionsStore ¶
type SessionsStore interface { // Create stores the provided Session. Implementations MUST return an error if // a Session having the indicated identifier already exists. Create(context.Context, Session) error // GetByHashedOAuth2State returns a Session having the indicated secure hash // of the OAuth 2 "state" code. This is used in completing both OpenID Connect // and GitHub authentication workflows. If no such Session exists, // implementations MUST return a *meta.ErrNotFound error. GetByHashedOAuth2State(context.Context, string) (Session, error) // GetByHashedToken returns a Session having the indicated secure hash of the // opaque bearer token. If no such Session exists, implementations MUST // return a *meta.ErrNotFound error. GetByHashedToken(context.Context, string) (Session, error) // Authenticate updates the specified, as-yet-anonymous Session (with an // as-yet unactivated token) to denote ownership by the indicated User and to // assign the specified expiry date/time. This is used in completing // third-party authentication workflows. Authenticate( ctx context.Context, sessionID string, userID string, expires time.Time, ) error // Delete deletes the specified Session. If no Session having the given // identifier is found, implementations MUST return a *meta.ErrNotFound error. Delete(context.Context, string) error // DeleteByUser deletes all sessions belonging to the specified User. DeleteByUser(ctx context.Context, userID string) error }
SessionsStore is an interface for Session persistence operations.
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 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 ThirdPartyAuthDetails ¶
type ThirdPartyAuthDetails struct { // AuthURL is a URL that can be requested in a user's web browser to complete // authentication via a third-party identity provider. AuthURL string `json:"authURL"` // Token is an opaque bearer token issued by Brigade to correlate a User with // a Session. It remains unactivated (useless) until the authentication // workflow is successfully completed. Clients may expect that that the token // expires (at an interval determined by a system administrator) and, for // simplicity, is NOT refreshable. When the token has expired, // re-authentication is required. Token string `json:"token"` }
ThirdPartyAuthDetails encapsulates all information required for a client authenticating by means of a third-party identity provider to complete the authentication workflow.
func (ThirdPartyAuthDetails) MarshalJSON ¶
func (t ThirdPartyAuthDetails) MarshalJSON() ([]byte, error)
MarshalJSON amends ThirdPartyAuthDetails instances with type metadata.
type ThirdPartyAuthHelper ¶
type ThirdPartyAuthHelper interface { // AuthURL returns a URL to which a User may be redirected for purposes of // completing authentication using a third-party identity provider. AuthURL(oauth2State string) string // Exchange exchanges a code issued by a third-party identity provider for // User identity information. Exchange( ctx context.Context, oauth2State string, oauth2Code string, ) (ThirdPartyIdentity, error) }
ThirdPartyAuthHelper is an interface for components that implement pluggable portions of third party authentication schemes based on OAuth2. OpenID Connect (used by certain identity providers like Azure Active Directory or Google Cloud Identity Platform) is built on top of OAuth2 (strictly speaking OAuth2 is for authorization; not authentication, but OpenID Connect extends OAuth2 with an authentication standard), but other authentication schemes (like GitHub's) are ALSO based on OAuth2, but DON'T implement OpenID Connect. This interface allows universal parts of authentication based on OAuth2 to be common for all third-party identity providers while utilizing standard-specific or provider-specific functionality for the portions of those authentication schemes that vary.
type ThirdPartyAuthOptions ¶
type ThirdPartyAuthOptions struct { // SuccessURL indicates where users should be redirected to after successful // completion of a third-party authentication workflow. If this is left // unspecified, users will be redirected to a default success page. SuccessURL string }
ThirdPartyAuthOptions encapsulates user-specified options when creating a new Session that will authenticate using a third-party identity provider.
type ThirdPartyAuthStrategy ¶
type ThirdPartyAuthStrategy string
type ThirdPartyIdentity ¶
type ThirdPartyIdentity struct { // ID is a handle or email address for the User. ID string // Name is the User's given name + surname. Name string }
ThirdPartyIdentity encapsulates ID (handle or email address) and name information for a User obtained from a third-party identity provider.
type Token ¶
type Token struct {
Value string `json:"value" bson:"value"`
}
Token represents an opaque bearer token used to authenticate to the Brigade API.
func (Token) MarshalJSON ¶
MarshalJSON amends Token instances with type metadata.
type User ¶
type User struct { // ObjectMeta encapsulates User metadata. meta.ObjectMeta `json:"metadata" bson:",inline"` // Name is the given name and surname of the User. Name string `json:"name" bson:"name"` // Locked indicates when the User has been locked out of the system by an // administrator. If this field's value is nil, the User is not locked. Locked *time.Time `json:"locked" bson:"locked"` }
User represents a (human) Brigade user.
func (User) MarshalJSON ¶
MarshalJSON amends User instances with type metadata.
type UserList ¶
type UserList struct { // ListMeta contains list metadata. meta.ListMeta `json:"metadata"` // Items is a slice of Users. Items []User `json:"items,omitempty"` }
UserList is an ordered and pageable list of Users.
func (UserList) MarshalJSON ¶
MarshalJSON amends UserList instances with type metadata.
type UsersService ¶
type UsersService interface { // List returns a UserList. List(context.Context, meta.ListOptions) (UserList, error) // Get retrieves a single User specified by their identifier. Get(context.Context, string) (User, error) // Lock removes access to the API for a single User specified by their // identifier. Lock(context.Context, string) error // Unlock restores access to the API for a single User specified by their // identifier. Unlock(context.Context, string) error // Delete removes a single User specified by their identifier. Delete(context.Context, string) error }
UsersService is the specialized interface for managing Users. It's decoupled from underlying technology choices (e.g. data store) to keep business logic reusable and consistent while the underlying tech stack remains free to change.
func NewUsersService ¶
func NewUsersService( authorizeFn AuthorizeFn, usersStore UsersStore, sessionsStore SessionsStore, roleAssignmentsStore RoleAssignmentsStore, projectRoleAssignmentsStore ProjectRoleAssignmentsStore, config UsersServiceConfig, ) UsersService
NewUsersService returns a specialized interface for managing Users.
type UsersServiceConfig ¶
type UsersServiceConfig struct { // ThirdPartyAuthEnabled indicates whether authentication using a third-party // identity provider is supported by the Sessions service. ThirdPartyAuthEnabled bool }
UsersServiceConfig encapsulates several configuration options for the UsersService.
type UsersStore ¶
type UsersStore interface { // Create persists a new User in the underlying data store. If a User having // the same ID already exists, implementations MUST return a *meta.ErrConflict // error. Create(context.Context, User) error // List retrieves a UserList from the underlying data store, with its Items // (Users) ordered by ID. List(context.Context, meta.ListOptions) (UserList, error) // Get retrieves a single User from the underlying data store. Implementations // MUST use a case insensitive query for this operation. If the specified User // does not exist, implementations MUST return a *meta.ErrNotFound error. Get(context.Context, string) (User, error) // Lock updates the specified User in the underlying data store to reflect // that it has been locked out of the system. Implementations MUST use a case // insensitive update statement for this operation. If the specified User does // not exist, implementations MUST return a *meta.ErrNotFound error. Lock(context.Context, string) error // Unlock updates the specified User in the underlying data store to reflect // that its system access (after presumably having been revoked) has been // restored. Implementations MUST use a case insensitive update statement for // this operation. If the specified User does not exist, implementations MUST // return a *meta.ErrNotFound error. Unlock(ctx context.Context, id string) error // Delete deletes the specified User. If no User having the given identifier // is found, implementations MUST return a *meta.ErrNotFound error. Delete(context.Context, string) error }
UsersStore is an interface for User persistence operations.
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.
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 // TimeoutDuration specifies the time duration that must elapse before a // running Job should be considered to have timed out. This duration string // is a possibly signed sequence of decimal numbers, each with optional // fraction and a unit suffix, such as "300ms", "-1.5h" or "2h45m". // Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". TimeoutDuration string `json:"timeoutDuration,omitempty" bson:"timeoutDuration,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 // Timeout updates the status of an Event's Worker that has timed out and // then proceeds to remove Worker-related resources from the substrate. Timeout(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 AuthorizeFn, projectsStore ProjectsStore, eventsStore EventsStore, workersStore WorkersStore, substrate Substrate, ) WorkersService
NewWorkersService returns a specialized interface for managing Workers.
Source Files ¶
- authorizers.go
- containers.go
- events.go
- jobs.go
- logs.go
- named_project_roles.go
- named_roles.go
- named_special_roles.go
- principals.go
- project_authorizers.go
- project_role_assignments.go
- project_roles.go
- projects.go
- qualifiers.go
- role_assignments.go
- roles.go
- secrets.go
- service_accounts.go
- sessions.go
- substrate.go
- third_party_auth_helper.go
- tokens.go
- users.go
- workers.go