Documentation
¶
Overview ¶
Package gapi holds what Google Cloud services share: the REST mirror that maps JSON/HTTP calls onto a service's gRPC handlers, Google-style errors, and the long-running operations service (google.longrunning.Operations).
Index ¶
- Constants
- Variables
- func AccessToken(email, scope string, ttl time.Duration) string
- func Bool(v string) bool
- func Cert(k *rsa.PrivateKey, cn string) []byte
- func Client(h *core.Hub) *http.Client
- func Decode(msg proto.Message, in map[string]any) error
- func Err(w http.ResponseWriter, c *core.Ctx, err error)
- func Exists(format string, a ...any) error
- func Invalid(format string, a ...any) error
- func JSON(w http.ResponseWriter, out any)
- func JSONErr(w http.ResponseWriter, c *core.Ctx, code int, name, msg string)
- func JWK(kid string, pub *rsa.PublicKey) map[string]any
- func NotFound(format string, a ...any) error
- func OAuthToken() string
- func OIDCToken(email, audience string) string
- func PEM(typ string, der []byte) []byte
- func Page[T any](items []T, size int32, token string) ([]T, string)
- func PageSizeOK(v string) bool
- func ParseBody(b []byte, field string) (map[string]any, error)
- func PlainProto(body []byte, err error) string
- func Policy(cur *iampb.Policy) *iampb.Policy
- func ProxyDesc(sd *grpc.ServiceDesc, conn func(context.Context) (*grpc.ClientConn, error), ...) *grpc.ServiceDesc
- func PublicKey() *rsa.PublicKey
- func SetPolicy(cur, in *iampb.Policy) (*iampb.Policy, error)
- func SetSigningKey(k *rsa.PrivateKey)
- func SignJWT(kid string, k *rsa.PrivateKey, claims any) string
- func SigningKey() *rsa.PrivateKey
- func Status(httpCode int, err error) *spb.Status
- func Update(dst, src proto.Message, paths []string, allowed ...string) error
- type Filter
- type JWT
- type KeyDirectory
- type Mux
- type Ops
- func (o *Ops) CancelOperation(ctx context.Context, r *longrunningpb.CancelOperationRequest) (*emptypb.Empty, error)
- func (o *Ops) Delegate(client func() longrunningpb.OperationsClient)
- func (o *Ops) DeleteOperation(ctx context.Context, r *longrunningpb.DeleteOperationRequest) (*emptypb.Empty, error)
- func (o *Ops) Done(parent string, meta, resp proto.Message) *longrunningpb.Operation
- func (o *Ops) DoneJSON(parent string, meta, resp map[string]any) map[string]any
- func (o *Ops) GetOperation(ctx context.Context, r *longrunningpb.GetOperationRequest) (*longrunningpb.Operation, error)
- func (o *Ops) Info() core.Info
- func (o *Ops) ListOperations(ctx context.Context, r *longrunningpb.ListOperationsRequest) (*longrunningpb.ListOperationsResponse, error)
- func (o *Ops) RegisterGRPC(g *grpc.Server)
- func (o *Ops) Reset()
- func (o *Ops) ServeHTTP(w http.ResponseWriter, r *http.Request)
- func (o *Ops) Start(parent string, meta proto.Message, run func() (proto.Message, error)) *longrunningpb.Operation
- func (o *Ops) WaitOperation(ctx context.Context, r *longrunningpb.WaitOperationRequest) (*longrunningpb.Operation, error)
- type REST
- type Route
- type Rule
- type Token
Constants ¶
const KeyID = "pogi"
KeyID is the kid of the shared signing key.
const MaxPageSize = 1000
MaxPageSize is the largest page Page returns; Google caps a bigger page size instead of refusing it. (A negative size is refused earlier, in invoke.)
Variables ¶
var EmptyEtag = []byte{0, 0, 1}
EmptyEtag is the etag of a policy that was never set.
var Regions = []string{"us-central1", "us-east1", "us-east4", "us-west1", "us-west2", "europe-west1", "europe-west2", "europe-west3",
"europe-west4", "asia-east1", "asia-northeast1", "asia-south1", "asia-southeast1", "australia-southeast1", "southamerica-east1"}
Regions are the Google Cloud regions pogi lists: Compute Engine's regions, Cloud Tasks' locations.
Functions ¶
func AccessToken ¶
AccessToken returns an opaque ya29 access token that carries its email, scope and expiry, authenticated so Token reads it back. Nothing is stored.
func Bool ¶ added in v0.2.0
Bool reads a true/false query value. Google accepts any case, and the Python clients send True.
func Cert ¶
func Cert(k *rsa.PrivateKey, cn string) []byte
Cert makes a self-signed X.509 certificate (DER) for a key, as Google publishes for service account keys.
func Client ¶
Client is the HTTP client for calls a service makes to user targets (Cloud Tasks, Scheduler, Eventarc). A *.localhost host (<svc>.run.localhost) goes to pogi's own port with its Host header kept, so no DNS is involved. It follows no redirects: a 3xx is a failed delivery, as at Google.
func Decode ¶
Decode fills a request message from the JSON members in. It refuses an unknown enum name and a negative page_size, as Google does. Unknown fields are dropped.
func Err ¶
func Err(w http.ResponseWriter, c *core.Ctx, err error)
Err renders a gRPC status as a Google REST error.
func JSON ¶
func JSON(w http.ResponseWriter, out any)
JSON writes a 200 response: protojson for a proto message, encoding/json for the rest.
func OAuthToken ¶
func OAuthToken() string
OAuthToken returns an access token for no one in particular.
func OIDCToken ¶
OIDCToken returns an RS256 ID token for the service account, as Google would send it: iss, sub, azp, email, email_verified, aud, iat and exp.
func PageSizeOK ¶
PageSizeOK says whether v can be a maxResults query value: empty, or a whole number from 0 to 2^32-1. A bigger size is capped, a negative or non-numeric one is refused with a 400.
func ParseBody ¶
ParseBody reads a JSON request body into the map that Decode turns into a request. field is the request member the body fills ("" means the body is the request). A body of null is an empty message.
func PlainProto ¶ added in v0.2.0
PlainProto says in plain words why a protojson body was refused. protojson reports "syntax error" even for a field of the wrong type, so a body that is valid JSON gets the wrong-type sentence. Go's text follows.
func ProxyDesc ¶ added in v0.2.0
func ProxyDesc(sd *grpc.ServiceDesc, conn func(context.Context) (*grpc.ClientConn, error), check func(proto.Message) error) *grpc.ServiceDesc
ProxyDesc returns a copy of a generated service description whose methods forward every call to another gRPC server: a vendor's emulator that runs behind pogi. Register it with a nil implementation. conn is called on each call and may start the backend; its error is the call's error. check, if not nil, sees each request first and may refuse it. Methods that stream from the client are left out (the server answers Unimplemented): the backends here (Spanner, Bigtable's emulator) have none.
func SetPolicy ¶
SetPolicy returns the policy to store when in replaces cur (nil if never set). A non-empty etag that isn't cur's is a concurrent change, as at Google. Bindings without members are dropped.
func SetSigningKey ¶
func SetSigningKey(k *rsa.PrivateKey)
SetSigningKey installs a saved signing key.
func SignJWT ¶
func SignJWT(kid string, k *rsa.PrivateKey, claims any) string
SignJWT signs claims with RS256.
func SigningKey ¶
func SigningKey() *rsa.PrivateKey
SigningKey is pogi's stand-in for Google's own ID-token key. It signs every ID token (OIDCToken: IAM Credentials, the token endpoint, Cloud Tasks and Scheduler) and its public half is served at /oauth2/v3/certs. It is made on first use; the IAM service keeps it across restarts with SetSigningKey.
Types ¶
type Filter ¶
type Filter struct {
// contains filtered or unexported fields
}
Filter is a parsed Google filter expression, in the syntax Cloud Logging and Cloud Monitoring share: terms joined by AND (or just a space) and OR, NOT or -, and parentheses. OR binds tighter than AND, as in Logging.
field OP value OP is one of = != > >= < <= : =~ !~
field = fn(a, b) a value function (Monitoring: starts_with, one_of, ...)
fn(a, b) a function alone (Logging: log_id("x"))
word, "a phrase" a global text search
The service gives the terms their meaning: see Match.
func ParseFilter ¶
ParseFilter parses a filter; the empty filter matches everything.
type KeyDirectory ¶
type KeyDirectory interface {
// ServiceAccountKeys returns the enabled public keys of an enabled
// service account by key id; nil when it doesn't exist or is disabled.
ServiceAccountKeys(email string) map[string]*rsa.PublicKey
}
KeyDirectory is what the IAM service offers the token endpoint.
type Mux ¶
type Mux struct {
// contains filtered or unexported fields
}
Mux serves Rules by calling a service's gRPC handlers, the way REST does.
type Ops ¶
type Ops struct {
longrunningpb.UnimplementedOperationsServer
// contains filtered or unexported fields
}
Ops is the shared google.longrunning.Operations service: every GCP service that returns an Operation stores it here, and clients poll it by name over gRPC or REST (GET /v1|v2/projects/p/locations/l/operations/o).
ponytail: operations are in memory only and never expire; persist them if a restart mid-operation ever matters.
func Operations ¶
Operations returns the hub's operations service, or a detached one when "operations" is disabled (clients then can't poll, but done ops still work).
func (*Ops) CancelOperation ¶
func (o *Ops) CancelOperation(ctx context.Context, r *longrunningpb.CancelOperationRequest) (*emptypb.Empty, error)
CancelOperation marks a running operation CANCELLED; the work itself runs on.
func (*Ops) Delegate ¶ added in v0.2.0
func (o *Ops) Delegate(client func() longrunningpb.OperationsClient)
Delegate adds a backend for the operations that are not stored here: the emulator behind a service (Spanner's) keeps its own. client returns nil while the backend is not running, and then it knows no operation.
func (*Ops) DeleteOperation ¶
func (o *Ops) DeleteOperation(ctx context.Context, r *longrunningpb.DeleteOperationRequest) (*emptypb.Empty, error)
func (*Ops) Done ¶
Done records a finished operation under parent (projects/p/locations/l, or "" for a top-level operations/<id>) with resp as its result; meta may be nil.
func (*Ops) DoneJSON ¶ added in v0.2.0
DoneJSON records a finished operation under parent whose metadata and response are JSON objects (a generic REST engine's resources, which no proto message describes). A GET or :wait of it answers {"name", "metadata", "done": true, "response"}; list, cancel and delete treat it like any other.
func (*Ops) GetOperation ¶
func (o *Ops) GetOperation(ctx context.Context, r *longrunningpb.GetOperationRequest) (*longrunningpb.Operation, error)
func (*Ops) ListOperations ¶
func (o *Ops) ListOperations(ctx context.Context, r *longrunningpb.ListOperationsRequest) (*longrunningpb.ListOperationsResponse, error)
func (*Ops) RegisterGRPC ¶
func (*Ops) Start ¶
func (o *Ops) Start(parent string, meta proto.Message, run func() (proto.Message, error)) *longrunningpb.Operation
Start records a running operation and finishes it with run's result in the background; Get and Wait see it as done once run returns.
func (*Ops) WaitOperation ¶
func (o *Ops) WaitOperation(ctx context.Context, r *longrunningpb.WaitOperationRequest) (*longrunningpb.Operation, error)
type REST ¶
type REST struct {
Versions []string // path versions, e.g. {"v2"}
Collections []string // first collection after projects/<p>[/locations/<l>] that this service claims
Desc *grpc.ServiceDesc
Impl any // the gRPC server implementation
Routes map[string]Route
}
REST serves a Google API's REST surface by calling its gRPC handlers.
Routes are keyed "VERB shape[:verb]", where shape is the path after /<version>/projects/<p>/ with every resource id replaced by "*":
"POST locations/*/services" → parent = projects/p/locations/l "GET locations/*/services/*" → name = projects/p/locations/l/services/s "POST locations/*/jobs/*:run" → name = projects/p/locations/l/jobs/j
The resource name is the path up to its last even segment, so collection calls get the parent and item calls get the item. Query parameters become request fields by their JSON names (serviceId, pageSize, updateMask).
type Route ¶
type Route struct {
Method string // gRPC method name, e.g. "CreateService"
Field string // request field the path's resource name fills, dotted ("parent", "service.name")
Body string // request field the JSON body fills; "" means the whole body is the request
Desc *grpc.ServiceDesc // overrides REST.Desc for services with several gRPC services
}
Route maps one REST call onto a gRPC method.
type Rule ¶
type Rule struct {
HTTP string
Method string // gRPC method name; with Fn, the operation name shown in the request log
Body string // request field the JSON body fills; "" means the whole body is the request
// Fn handles the call instead of a gRPC method: r has the body in
// core.Body(r) and vars holds the path variables. A proto.Message is
// answered as protojson, anything else as plain JSON.
Fn func(r *http.Request, vars map[string]string) (any, error)
}
Rule is one REST call, written as in a google.api.http annotation:
"POST /v1/{name=projects/*/serviceAccounts/*}:disable"
"*" is one path segment and "**" the rest of the path. A {variable} fills the request field of that (dotted, JSON) name with the segments it covers. It is the Mux's answer to REST paths that REST's projects/<p>/<collection> shape can't express: organizations, top-level collections, ids without a "projects/" prefix.
type Token ¶
Token is what an access token carries.
func ParseAccessToken ¶
ParseAccessToken reads a token made by AccessToken; ok is false for any other string, and for one that has expired.