Documentation
¶
Overview ¶
Package status is the contract between the GitHub controller and the console: what the controller last did to each organisation, and why, written where the console can read it.
It is a ConfigMap and not an API, for the reasons everything else this service keeps is a Kubernetes object. The controller has no listener and must not grow one: it holds App keys and writes to GitHub, and a port would be a way in. An operator reads the same object with kubectl that the console renders. And a console that cannot reach the controller still shows what it last reported, with the time it did.
One key per organisation, each a versioned JSON document, so an organisation's state is read and written whole and a reader never has to join fragments.
Index ¶
- Constants
- Variables
- func ConfigMapName(release string) string
- func Encode(o Org) (string, error)
- func Key(org string) string
- func OrgOfKey(key string) (string, bool)
- func ValidOrg(org string) bool
- type Account
- type Action
- type Breaker
- type Member
- type Org
- type Outcome
- type ReportReader
- type Role
- type Seats
- type State
- type Team
- type Tick
Constants ¶
const Version = 1
Version is the document version this build writes and reads. A reader refuses any other: a console rendering a shape it does not know would show a confident page that means something else.
Variables ¶
var ErrVersion = errors.New("status: unsupported document version")
ErrVersion is a document of a version this build does not read.
Functions ¶
func ConfigMapName ¶
ConfigMapName is the status object for a release.
func Encode ¶
Encode writes one organisation's document, in a fixed order, so that `kubectl diff` between two ticks shows what changed rather than what moved. It never reorders the caller's own slices.
Types ¶
type Breaker ¶
type Breaker struct {
// Affected is how many accounts the removals concern, and Members how
// many the organisation has.
Affected int `json:"affected"`
Members int `json:"members"`
// Fingerprint names exactly this set of removals. Confirming it lets
// this set, and no other, go ahead.
Fingerprint string `json:"fingerprint"`
// Confirmed is whether an operator confirmed this set, so the pass
// went ahead.
Confirmed bool `json:"confirmed,omitempty"`
}
Breaker is a pass that would have removed more than half the organisation.
type Member ¶
type Member struct {
Email string `json:"email,omitempty"`
// Login is empty for somebody not yet linked to a GitHub account —
// whom the controller will invite by address.
Login string `json:"login,omitempty"`
Role Role `json:"role"`
State State `json:"state"`
// Action is what the controller does, or would do, to make this
// person's membership true. Empty when synced.
Action Action `json:"action,omitempty"`
// Reason is why an action is held, or anything else worth reading
// beside the state.
Reason string `json:"reason,omitempty"`
}
Member is one person in a team or in the organisation's own binding: who, as what, and whether that is already true.
type Org ¶
type Org struct {
Version int `json:"version"`
Org string `json:"org"`
// Enabled is whether the controller acts on this organisation. A
// disabled one is still derived every tick, and its members' states
// say what WOULD change: that is how an organisation is enabled
// knowingly rather than hopefully.
Enabled bool `json:"enabled"`
Tick Tick `json:"tick"`
// Members are the organisation-level binding's holders: people who
// belong in the organisation with or without a team.
Members []Member `json:"members,omitempty"`
Teams []Team `json:"teams,omitempty"`
// Unlinked are members nobody linked to a work address: nobody can say
// who they are, so they are listed and never touched.
Unlinked []Account `json:"unlinked,omitempty"`
// OutsideCollaborators have access to repositories without being
// members. Reported, never managed.
OutsideCollaborators []Account `json:"outside_collaborators,omitempty"`
// Seats is the organisation's seats as last read, or nil before the
// controller could read anything.
Seats *Seats `json:"seats,omitempty"`
// Breaker is set when this pass would have removed more than half the
// organisation, and so removed nobody.
Breaker *Breaker `json:"breaker,omitempty"`
}
Org is one organisation's report.
type Outcome ¶
type Outcome string
Outcome is a tick's result, as one word.
const ( // OutcomeInSync: nothing to do. OutcomeInSync Outcome = "in-sync" // OutcomeApplied: changes were made. OutcomeApplied Outcome = "applied" // OutcomeDryRun: the organisation is disabled, and Changes counts // what would have been done. OutcomeDryRun Outcome = "dry-run" // OutcomeHeld: something was to be done and every such action was // held. Not a failure — each has its reason on the member. OutcomeHeld Outcome = "held" // OutcomeRetrying: every action this pass could not be taken for a // reason that clears on its own, and is tried again next pass. OutcomeRetrying Outcome = "retrying" // OutcomeWaiting: nothing to do and nothing held, and people the // policy wants have not linked an account yet. Not in sync: enabling // the organisation would change nothing for them. OutcomeWaiting Outcome = "waiting" // OutcomeFailed: the tick could not complete. OutcomeFailed Outcome = "failed" )
The outcomes.
type ReportReader ¶ added in v1.76.0
ReportReader is where the console reads what the GitHub controller last reported: the documents of the status contract, keyed as written.
type Seats ¶
type Seats struct {
// Known is false when GitHub would not say: the App lacks organisation
// administration (read). Nobody is invited while it is.
Known bool `json:"known"`
Total int `json:"total,omitempty"`
Filled int `json:"filled,omitempty"`
// Pending are invitations waiting to be accepted, which take a seat
// once accepted and may already be counted in Filled; counted here
// again, so the controller errs towards inviting too few.
Pending int `json:"pending,omitempty"`
// Free is Total - Filled - Pending, never below zero.
Free int `json:"free"`
// Short is how many invitations this pass could not send for want of a
// seat.
Short int `json:"short,omitempty"`
}
Seats is what the organisation pays for, beside what the policy wants.
type State ¶
type State string
State is where one person's membership stands.
const ( // StateNotLinked: they should be here and have not linked a GitHub // account, so there is nobody to invite. Waiting on them, not held. StateNotLinked State = "not-linked" // StatePending: they should be here and are not yet; Action says what // comes next. StatePending State = "pending" // StateInvited: an organisation invitation to their account, or to // their address, is waiting to be accepted. StateInvited State = "invited" // StateSynced: what is true matches what should be. StateSynced State = "synced" // StateLeaving: they are here and should not be; Action says what // comes next. StateLeaving State = "leaving" // StateHeld: something is to be done and is not being done until a // person acts — a team missing on GitHub, no free seat, a removal over // the limit waiting for confirmation. Reason says why. StateHeld State = "held" // StateRetrying: something is to be done and could not be this pass, // for a reason that clears on its own — the directory cannot vouch for // somebody right now, GitHub refused a change. Tried again next pass. StateRetrying State = "retrying" // StateIgnored: they linked an account and let two invitations expire. // Not invited again until they link again. StateIgnored State = "ignored" // StateReported: an organisation owner the policy would change. // Owners and billing are managed outside; this is said, never done. StateReported State = "reported" )
The states, in the order a joiner passes through them.
type Tick ¶
type Tick struct {
At time.Time `json:"at"`
Outcome Outcome `json:"outcome"`
// Error is why a failed tick failed, in words an operator can act on.
Error string `json:"error,omitempty"`
// Changes is how many actions were taken — or, when disabled, would
// have been.
Changes int `json:"changes"`
// Held is how many actions were not taken, each for a reason given on
// the member it concerns, until a person acts.
Held int `json:"held"`
// Retrying is how many actions could not be taken this pass and will be
// tried again.
Retrying int `json:"retrying,omitempty"`
// Waiting is how many rows want somebody who has not linked a GitHub
// account: nothing the controller can do, and not in sync either.
Waiting int `json:"waiting,omitempty"`
}
Tick is how the last pass over the organisation went.