Documentation
¶
Index ¶
- Constants
- func AddAsyncOperationHeader(writer http.ResponseWriter, request *http.Request, ...)
- func AddLocationHeader(writer http.ResponseWriter, request *http.Request, ...)
- func BodyFromContext(ctx context.Context) ([]byte, error)
- func ContextWithBody(ctx context.Context, body []byte) context.Context
- func ContextWithCorrelationData(ctx context.Context, correlationData *arm.CorrelationData) context.Context
- func ContextWithOriginalPath(ctx context.Context, originalPath string) context.Context
- func ContextWithPattern(ctx context.Context, pattern *string) context.Context
- func ContextWithSystemData(ctx context.Context, systemData *arm.SystemData) context.Context
- func ContextWithVersion(ctx context.Context, version api.Version) context.Context
- func CorrelationDataFromContext(ctx context.Context) (*arm.CorrelationData, error)
- func MiddlewareBody(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)
- func MiddlewareCorrelationData(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)
- func MiddlewareLogging(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)
- func MiddlewareLoggingPostMux(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)
- func MiddlewareLowercase(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)
- func MiddlewarePanic(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)
- func MiddlewareReferer(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)
- func MiddlewareResourceID(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)
- func MiddlewareSystemData(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)
- func MiddlewareTracing(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)
- func MigrateCosmosOrDie(ctx context.Context, cosmosClient database.DBClient)
- func MuxPattern(method string, segments ...string) string
- func OriginalPathFromContext(ctx context.Context) (string, error)
- func PatternFromContext(ctx context.Context) *string
- func RequestIDPropagator(next http.RoundTripper) http.RoundTripper
- func SystemDataFromContext(ctx context.Context) (*arm.SystemData, error)
- func VersionFromContext(ctx context.Context) (api.Version, error)
- type ContextError
- type Frontend
- func (f *Frontend) ArmDeploymentPreflight(writer http.ResponseWriter, request *http.Request) error
- func (f *Frontend) ArmResourceActionRequestAdminCredential(writer http.ResponseWriter, request *http.Request) error
- func (f *Frontend) ArmResourceActionRevokeCredentials(writer http.ResponseWriter, request *http.Request) error
- func (f *Frontend) ArmResourceListClusters(writer http.ResponseWriter, request *http.Request) error
- func (f *Frontend) ArmResourceListExternalAuths(writer http.ResponseWriter, request *http.Request) error
- func (f *Frontend) ArmResourceListNodePools(writer http.ResponseWriter, request *http.Request) error
- func (f *Frontend) ArmResourceListVersion(writer http.ResponseWriter, request *http.Request) error
- func (f *Frontend) ArmSubscriptionGet(writer http.ResponseWriter, request *http.Request) error
- func (f *Frontend) ArmSubscriptionPut(writer http.ResponseWriter, request *http.Request) error
- func (f *Frontend) CancelActiveOperations(ctx context.Context, transaction database.DBTransaction, ...) error
- func (f *Frontend) CreateOrUpdateExternalAuth(writer http.ResponseWriter, request *http.Request) error
- func (f *Frontend) CreateOrUpdateHCPCluster(writer http.ResponseWriter, request *http.Request) error
- func (f *Frontend) CreateOrUpdateNodePool(writer http.ResponseWriter, request *http.Request) error
- func (f *Frontend) DeleteAllResourcesInSubscription(ctx context.Context, subscriptionID string) error
- func (f *Frontend) DeleteCluster(writer http.ResponseWriter, request *http.Request) error
- func (f *Frontend) DeleteExternalAuth(writer http.ResponseWriter, request *http.Request) error
- func (f *Frontend) DeleteNodePool(writer http.ResponseWriter, request *http.Request) error
- func (f *Frontend) GetExternalAuth(writer http.ResponseWriter, request *http.Request) error
- func (f *Frontend) GetHCPCluster(writer http.ResponseWriter, request *http.Request) error
- func (f *Frontend) GetNodePool(writer http.ResponseWriter, request *http.Request) error
- func (f *Frontend) GetOpenshiftVersions(writer http.ResponseWriter, request *http.Request) error
- func (f *Frontend) Healthz(writer http.ResponseWriter, request *http.Request)
- func (f *Frontend) Location(writer http.ResponseWriter, request *http.Request)
- func (f *Frontend) NotFound(writer http.ResponseWriter, request *http.Request)
- func (f *Frontend) OperationIsVisible(request *http.Request, operation *api.Operation) bool
- func (f *Frontend) OperationResult(writer http.ResponseWriter, request *http.Request) error
- func (f *Frontend) OperationStatus(writer http.ResponseWriter, request *http.Request) error
- func (f *Frontend) Run(ctx context.Context) error
- type LoggingReadCloser
- type LoggingResponseWriter
- type MetricsMiddleware
- type Middleware
- type MiddlewareFunc
- type MiddlewareMux
- type SubscriptionStateGetter
Constants ¶
const ( ProgramName = "ARO HCP Frontend" // APIVersionKey is the request parameter name for the API version. APIVersionKey = "api-version" // Wildcard path segment names for request multiplexing. // Must be lowercase as we lowercase the request URL pattern // when registering handlers. PathSegmentDeploymentName = "deploymentname" PathSegmentLocation = "location" PathSegmentNodePoolName = "nodepoolname" PathSegmentExternalAuthName = "externalauthname" PathSegmentOperationID = "operationid" PathSegmentResourceGroupName = "resourcegroupname" PathSegmentResourceName = "resourcename" PathSegmentSubscriptionID = "subscriptionid" )
const ( UnregisteredSubscriptionStateMessage = "Request is not allowed in unregistered subscription '%s'." InvalidSubscriptionStateMessage = "Request is not allowed in subscription in state '%s'." SubscriptionMissingMessage = "The request is missing required parameter '%s'." )
const ( WildcardDeploymentName = "{" + PathSegmentDeploymentName + "}" WildcardLocation = "{" + PathSegmentLocation + "}" WildcardNodePoolName = "{" + PathSegmentNodePoolName + "}" WildcardExternalAuthName = "{" + PathSegmentExternalAuthName + "}" WildcardOperationID = "{" + PathSegmentOperationID + "}" WildcardResourceGroupName = "{" + PathSegmentResourceGroupName + "}" WildcardResourceName = "{" + PathSegmentResourceName + "}" WildcardSubscriptionID = "{" + PathSegmentSubscriptionID + "}" PatternSubscriptions = "subscriptions/" + WildcardSubscriptionID PatternLocations = "locations/" + WildcardLocation PatternProviders = "providers/" + api.ProviderNamespace PatternClusters = api.ClusterResourceTypeName + "/" + WildcardResourceName PatternNodePools = api.NodePoolResourceTypeName + "/" + WildcardNodePoolName PatternVersions = api.VersionResourceTypeName + "/" + WildcardResourceName PatternExternalAuth = api.ExternalAuthResourceTypeName + "/" + WildcardExternalAuthName PatternDeployments = "deployments/" + WildcardDeploymentName PatternResourceGroups = "resourcegroups/" + WildcardResourceGroupName PatternOperationResults = api.OperationResultResourceTypeName + "/" + WildcardOperationID PatternOperationStatuses = api.OperationStatusResourceTypeName + "/" + WildcardOperationID ActionRequestAdminCredential = "requestadmincredential" ActionRevokeCredentials = "revokecredentials" )
Variables ¶
This section is empty.
Functions ¶
func AddAsyncOperationHeader ¶
func AddAsyncOperationHeader(writer http.ResponseWriter, request *http.Request, operationID *azcorearm.ResourceID)
AddAsyncOperationHeader adds an "Azure-AsyncOperation" header to the ResponseWriter with a URL of the operation status endpoint.
func AddLocationHeader ¶
func AddLocationHeader(writer http.ResponseWriter, request *http.Request, operationID *azcorearm.ResourceID)
AddLocationHeader adds a "Location" header to the ResponseWriter with a URL of the operation result endpoint.
func ContextWithOriginalPath ¶
func ContextWithPattern ¶
func ContextWithSystemData ¶
func ContextWithVersion ¶
func CorrelationDataFromContext ¶
func CorrelationDataFromContext(ctx context.Context) (*arm.CorrelationData, error)
func MiddlewareBody ¶
func MiddlewareBody(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)
MiddlewareBody ensures that the request's body doesn't exceed the maximum size of 4MB.
func MiddlewareCorrelationData ¶
func MiddlewareCorrelationData(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)
MiddlewareCorrelationData reads the correlation data from the incoming request, extends the contextual logger with correlation attributes and adds the necessary X-ms-* headers to the HTTP response.
func MiddlewareLogging ¶
func MiddlewareLogging(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)
MiddlewareLogging logs the HTTP request and response.
func MiddlewareLoggingPostMux ¶
func MiddlewareLoggingPostMux(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)
MiddlewareLoggingPostMux extends the contextual logger with additional attributes after the request has been matched by the ServeMux.
func MiddlewareLowercase ¶
func MiddlewareLowercase(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)
This middleware helps comply with Azure OpenAPI Specifications Guidelines around case sensitivity for resource IDs. Specifically:
OAPI012: Resource IDs must not be case sensitive
Any entity name in the URL or resource ID (resource group names, resource names, resource provider names) must be treated case insensitively. RPs should also persist the casing provided by the user for tags, resource names, etc... and use that same casing in responses. Example: The following two resource IDs are both valid and point to the same resource. Casing must be ignored. /subscriptions/45cefb9a-1824-4c35-ab4b-05c78763c03e/resourceGroups/myResourceGroup/ providers/Microsoft.KeyVault/vaults/sample-vault?api-version=2019-09-01 /SUBSCRIPTIONS/45CEFB9A-1824-4C35-AB4B-05C78763C03E/RESOURCEGROUPS/myresourceGROUP/ PROVIDERS/MICROSOFT.keyvault/VAULTS/SAMPLE-VAULT?API-VERSION=2019-09-01
The frontend uses ServeMux from Go's standard library (net/http), which matches literal (that is, non-wildcarded) path segments case-sensitively. For instance, in a resource ID, "subscriptions" and "resourcegroups" are literal path segments and therefore are matched case-sensitvely.
So this middleware saves the original path casing in the request context, and then normalizes the casing for ServeMux by lowercasing it. At the same time, when registering URL patterns with ServeMux in routes.go, we use the helper function MuxPattern which also lowercases the path segments passed to it to ensure their normalized casing agrees with this middleware.
When the resource ID, or parts of it, needs to be used in an HTTP response (such as an error message), be sure to retrieve the original path from the request context. Do not use the normalized request path nor path values in the request (via PathValue). If necessary, you can parse the original path into a resource ID using ParseResourceID from the azcore/arm package.
func MiddlewarePanic ¶
func MiddlewarePanic(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)
func MiddlewareReferer ¶
func MiddlewareReferer(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)
MiddlewareReferer ensures a Referer header is present in the request. This header is always added by ARM but is often forgotten in testing environments. If missing, derive a Referer from the http.Request.
Referer headers are used in a few places: - The "nextLink" field in a paginated response body - "Location" and "Azure-AsyncOperation" response headers
func MiddlewareResourceID ¶
func MiddlewareResourceID(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)
This middleware only applies to endpoints whose path form a valid Azure resource ID. It should follow the MiddlewareLowercase function.
func MiddlewareSystemData ¶
func MiddlewareSystemData(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)
func MiddlewareTracing ¶
func MiddlewareTracing(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)
MiddlewareTracing starts an OpenTelemetry span wrapping all incoming HTTP requests. Other middlewares or actual request handlers can extend its metadata or create their own associated spans. The middleware expects that the trace provider is initialized and configured in advance.
func MigrateCosmosOrDie ¶
MigrateCosmosOrDie if migration fails, we panic and exit the process. This makes it very detectable.
func MuxPattern ¶
MuxPattern forms a URL pattern suitable for passing to http.ServeMux. Literal path segments must be lowercase because MiddlewareLowercase converts the request URL to lowercase before multiplexing.
func PatternFromContext ¶
func RequestIDPropagator ¶
func RequestIDPropagator(next http.RoundTripper) http.RoundTripper
RequestIDPropagator returns an http.RoundTripper interface which reads the request ID from the request's context and propagates it to the Clusters Service API via the "X-Request-ID" header.
func SystemDataFromContext ¶
func SystemDataFromContext(ctx context.Context) (*arm.SystemData, error)
Types ¶
type ContextError ¶
type ContextError struct {
// contains filtered or unexported fields
}
func (*ContextError) Error ¶
func (c *ContextError) Error() string
type Frontend ¶
type Frontend struct {
// contains filtered or unexported fields
}
func NewFrontend ¶
func NewFrontend( logger logr.Logger, listener net.Listener, metricsListener net.Listener, registry *prometheus.Registry, dbClient database.DBClient, csClient ocm.ClusterServiceClientSpec, auditClient audit.Client, azureLocation string, clusterServiceProvisionShard string, clusterServiceNoopProvision bool, clusterServiceNoopDeprovision bool, exitOnPanic bool, ) *Frontend
func NewTestFrontend ¶
func (*Frontend) ArmDeploymentPreflight ¶
func (*Frontend) ArmResourceActionRequestAdminCredential ¶
func (*Frontend) ArmResourceActionRevokeCredentials ¶
func (*Frontend) ArmResourceListClusters ¶
func (*Frontend) ArmResourceListExternalAuths ¶
func (*Frontend) ArmResourceListNodePools ¶
func (*Frontend) ArmResourceListVersion ¶
func (*Frontend) ArmSubscriptionGet ¶
func (*Frontend) ArmSubscriptionPut ¶
func (*Frontend) CancelActiveOperations ¶
func (f *Frontend) CancelActiveOperations(ctx context.Context, transaction database.DBTransaction, opts *database.DBClientListActiveOperationDocsOptions) error
CancelActiveOperations queries for operation documents with a non-terminal status using the filters specified in opts. For every document returned in the query result, CancelActiveOperations adds patch operations to the given DBTransaction to mark the document as canceled.
func (*Frontend) CreateOrUpdateExternalAuth ¶
func (*Frontend) CreateOrUpdateHCPCluster ¶
func (f *Frontend) CreateOrUpdateHCPCluster(writer http.ResponseWriter, request *http.Request) error
CreateOrUpdateHCPCluster handles both PUT and PATCH requests from clients to ARM. The semantics of these verbs are: When no resource by this identifier exists:
- PUT: create the resource, overlaying client-specified fields on a default resource struct, which only has API-specified non-zero default values
- PATCH: error
When a resource by this identifier already exists:
- PUT: replace the resource, overlaying client-specified fields on a default resource struct, which only has API-specified non-zero default values (and NOT taking into account the existing content of the resource in storage)
- PATCH: update the resource, overlaying client-specified fields onto the existing resource
This means all required properties must be specified in the request body for PUT, whether creating or updating a resource.
See these documents for a description of required semantics from ARM Resource Providers:
PUT: The Put operation creates or replaces a resource. Resource types can be nested and, if so, must follow the Resource API guidelines. ARM does not distinguish between creation and replacement requests. The resource provider should consult its datastore if a distinction is necessary. A Put should always be allowed to overwrite an existing resource. An exception to this rule is when `x-ms-mutability ['create', 'read']` is applied to a property. For such properties, the value submitted during the create operation must be retained. Eg: The location property defined for tracked resources. ref: https://github.com/cloud-and-ai-microsoft/resource-provider-contract/blob/master/v1.0/put-resource.md#put-resource
PATCH A Patch operation updates a resource and it is strongly recommended that service teams implement it. ARM requires RPs to support Patch for updating tags for a tracked resource. ref: https://github.com/cloud-and-ai-microsoft/resource-provider-contract/blob/master/v1.0/patch-resource.md#patch-resource
func (*Frontend) CreateOrUpdateNodePool ¶
func (*Frontend) DeleteAllResourcesInSubscription ¶
func (*Frontend) DeleteCluster ¶
DeleteCluster implements the deletion API contract for ARM * 200 if a deletion is successful * 202 if an asynchronous delete is initiated * 204 if a well-formed request attempts to delete a nonexistent resource
func (*Frontend) DeleteExternalAuth ¶
DeleteExternalAuth implements the deletion API contract for ARM * 200 if a deletion is successful * 202 if an asynchronous delete is initiated * 204 if a well-formed request attempts to delete a nonexistent resource
func (*Frontend) DeleteNodePool ¶
DeleteNodePool implements the deletion API contract for ARM * 200 if a deletion is successful * 202 if an asynchronous delete is initiated * 204 if a well-formed request attempts to delete a nonexistent resource
func (*Frontend) GetExternalAuth ¶
func (*Frontend) GetHCPCluster ¶
GetHCPCluster implements the GET single resource API contract for HCP Clusters * 200 If the resource exists * 404 If the resource does not exist
func (*Frontend) GetNodePool ¶
func (*Frontend) GetOpenshiftVersions ¶
GetOpenshiftVersions implements the GET single resource API contract for ARM * 200 If the resource exists * 404 If the resource does not exist
func (*Frontend) Healthz ¶
func (f *Frontend) Healthz(writer http.ResponseWriter, request *http.Request)
func (*Frontend) Location ¶
func (f *Frontend) Location(writer http.ResponseWriter, request *http.Request)
func (*Frontend) NotFound ¶
func (f *Frontend) NotFound(writer http.ResponseWriter, request *http.Request)
func (*Frontend) OperationIsVisible ¶
OperationIsVisible returns true if the request is being called from the same tenant and subscription that the operation originated in.
func (*Frontend) OperationResult ¶
func (*Frontend) OperationStatus ¶
type LoggingReadCloser ¶
type LoggingReadCloser struct {
io.ReadCloser
// contains filtered or unexported fields
}
type LoggingResponseWriter ¶
type LoggingResponseWriter struct {
http.ResponseWriter
// contains filtered or unexported fields
}
func (*LoggingResponseWriter) WriteHeader ¶
func (w *LoggingResponseWriter) WriteHeader(statusCode int)
type MetricsMiddleware ¶
type MetricsMiddleware struct {
// contains filtered or unexported fields
}
func NewMetricsMiddleware ¶
func NewMetricsMiddleware(r prometheus.Registerer, ssg SubscriptionStateGetter) *MetricsMiddleware
func (MetricsMiddleware) Metrics ¶
func (mm MetricsMiddleware) Metrics() MiddlewareFunc
Metrics middleware to capture response time and status code
type Middleware ¶
type Middleware struct {
// contains filtered or unexported fields
}
Middleware is a list of middleware functions to execute before invoking an http.Handler.
func NewMiddleware ¶
func NewMiddleware(functions ...MiddlewareFunc) *Middleware
NewMiddleware allocates and returns a new Middleware.
func (*Middleware) Handler ¶
func (m *Middleware) Handler(handler http.Handler) http.Handler
Handler returns an http.Handler that invokes the list of middleware functions before invoking the given HTTP handler. Pass the returned http.Handler to http.ServeMux.Handle to add middleware functions that execute after pattern-based multiplexing occurs and values for path wildcards are available via http.Request.PathValue.
func (*Middleware) HandlerFunc ¶
func (m *Middleware) HandlerFunc(handler func(http.ResponseWriter, *http.Request)) http.Handler
HandlerFunc returns an http.Handler that invokes the list of middleware functions before invoking the given HTTP handler function. Pass the returned http.Handler to http.ServeMux.Handle to add middleware functions that execute after pattern-based multiplexing occurs and values for path wildcards are available via http.Request.PathValue.
type MiddlewareFunc ¶
type MiddlewareFunc func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)
MiddlewareFunc specifies the call signature for middleware functions. At some point during normal execution, the middleware function must call the "next" handler function to invoke the next layer of request handling.
type MiddlewareMux ¶
MiddlewareMux is an http.ServeMux with middleware functions that execute before pattern-based multiplexing occurs.
func NewMiddlewareMux ¶
func NewMiddlewareMux(functions ...MiddlewareFunc) *MiddlewareMux
NewMiddlewareMux allocates and returns a new MiddlewareMux.
func (*MiddlewareMux) ServeHTTP ¶
func (mux *MiddlewareMux) ServeHTTP(w http.ResponseWriter, r *http.Request)
ServeHTTP dispatches the request to each middleware function, and then to the handler whose pattern most closely matches the request URL.
type SubscriptionStateGetter ¶
Source Files
¶
- cluster.go
- const.go
- context.go
- external_auth.go
- frontend.go
- helpers.go
- metrics.go
- middleware.go
- middleware_audit.go
- middleware_body.go
- middleware_correlation.go
- middleware_locksubscription.go
- middleware_logging.go
- middleware_lowercase.go
- middleware_panic.go
- middleware_referer.go
- middleware_resourceid.go
- middleware_systemdata.go
- middleware_tracing.go
- middleware_validateapi.go
- middleware_validatesubscription.go
- migrate_cosmos.go
- node_pool.go
- ocm.go
- operations.go
- routes.go
- testhelpers.go