Documentation
¶
Index ¶
- Constants
- 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 ContextWithDBClient(ctx context.Context, dbClient database.DBClient) context.Context
- func ContextWithLogger(ctx context.Context, logger *slog.Logger) context.Context
- func ContextWithOriginalPath(ctx context.Context, originalPath string) context.Context
- func ContextWithResourceID(ctx context.Context, resourceID *azcorearm.ResourceID) context.Context
- func ContextWithSystemData(ctx context.Context, systemData *arm.SystemData) context.Context
- func ContextWithVersion(ctx context.Context, version api.Version) context.Context
- func ConvertCStoHCPOpenShiftCluster(resourceID *azcorearm.ResourceID, cluster *cmv1.Cluster) *api.HCPOpenShiftCluster
- func ConvertCStoNodePool(resourceID *azcorearm.ResourceID, np *cmv1.NodePool) *api.HCPOpenShiftClusterNodePool
- func CorrelationDataFromContext(ctx context.Context) (*arm.CorrelationData, error)
- func DBClientFromContext(ctx context.Context) (database.DBClient, error)
- func LoggerFromContext(ctx context.Context) *slog.Logger
- func MiddlewareBody(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)
- func MiddlewareLockSubscription(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 MiddlewareResourceID(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)
- func MiddlewareSystemData(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)
- func MiddlewareValidateAPIVersion(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)
- func MiddlewareValidateStatic(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)
- func MiddlewareValidateSubscriptionState(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)
- func MuxPattern(method string, segments ...string) string
- func OriginalPathFromContext(ctx context.Context) (string, error)
- func ResourceIDFromContext(ctx context.Context) (*azcorearm.ResourceID, error)
- func SystemDataFromContext(ctx context.Context) (*arm.SystemData, error)
- func VersionFromContext(ctx context.Context) (api.Version, error)
- type ContextError
- type Emitter
- type Frontend
- func (f *Frontend) AddAsyncOperationHeader(writer http.ResponseWriter, request *http.Request, ...)
- func (f *Frontend) AddLocationHeader(writer http.ResponseWriter, request *http.Request, ...)
- func (f *Frontend) ArmDeploymentPreflight(writer http.ResponseWriter, request *http.Request)
- func (f *Frontend) ArmResourceAction(writer http.ResponseWriter, request *http.Request)
- func (f *Frontend) ArmResourceCreateOrUpdate(writer http.ResponseWriter, request *http.Request)
- func (f *Frontend) ArmResourceDelete(writer http.ResponseWriter, request *http.Request)
- func (f *Frontend) ArmResourceList(writer http.ResponseWriter, request *http.Request)
- func (f *Frontend) ArmResourceRead(writer http.ResponseWriter, request *http.Request)
- func (f *Frontend) ArmSubscriptionGet(writer http.ResponseWriter, request *http.Request)
- func (f *Frontend) ArmSubscriptionPut(writer http.ResponseWriter, request *http.Request)
- func (f *Frontend) BuildCSCluster(resourceID *azcorearm.ResourceID, requestHeader http.Header, ...) (*cmv1.Cluster, error)
- func (f *Frontend) BuildCSNodePool(ctx context.Context, nodePool *api.HCPOpenShiftClusterNodePool, updating bool) (*cmv1.NodePool, error)
- func (f *Frontend) CancelActiveOperation(ctx context.Context, resourceDoc *database.ResourceDocument) error
- func (f *Frontend) CheckForProvisioningStateConflict(ctx context.Context, operationRequest database.OperationRequest, ...) *arm.CloudError
- func (f *Frontend) CheckReady(ctx context.Context) bool
- func (f *Frontend) CreateOrUpdateNodePool(writer http.ResponseWriter, request *http.Request)
- func (f *Frontend) DeleteAllResources(ctx context.Context, subscriptionID string) *arm.CloudError
- func (f *Frontend) DeleteResource(ctx context.Context, resourceDoc *database.ResourceDocument) (string, *arm.CloudError)
- func (f *Frontend) ExposeOperation(writer http.ResponseWriter, request *http.Request, operationID string) error
- func (f *Frontend) Healthz(writer http.ResponseWriter, request *http.Request)
- func (f *Frontend) Join()
- func (f *Frontend) MarshalResource(ctx context.Context, resourceID *azcorearm.ResourceID, ...) ([]byte, *arm.CloudError)
- func (f *Frontend) NotFound(writer http.ResponseWriter, request *http.Request)
- func (f *Frontend) OperationIsVisible(request *http.Request, doc *database.OperationDocument) bool
- func (f *Frontend) OperationResult(writer http.ResponseWriter, request *http.Request)
- func (f *Frontend) OperationStatus(writer http.ResponseWriter, request *http.Request)
- func (f *Frontend) Run(ctx context.Context, stop <-chan struct{})
- type LoggingReadCloser
- type LoggingResponseWriter
- type MetricsMiddleware
- type Middleware
- type MiddlewareFunc
- type MiddlewareMux
- type PrometheusEmitter
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 PathSegmentActionName = "actionname" PathSegmentDeploymentName = "deploymentname" PathSegmentLocation = "location" PathSegmentNodePoolName = "nodepoolname" 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 ( WildcardActionName = "{" + PathSegmentActionName + "}" WildcardDeploymentName = "{" + PathSegmentDeploymentName + "}" WildcardLocation = "{" + PathSegmentLocation + "}" WildcardNodePoolName = "{" + PathSegmentNodePoolName + "}" 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 PatternDeployments = "deployments/" + WildcardDeploymentName PatternResourceGroups = "resourcegroups/" + WildcardResourceGroupName PatternOperationResults = api.OperationResultResourceTypeName + "/" + WildcardOperationID PatternOperationsStatus = api.OperationStatusResourceTypeName + "/" + WildcardOperationID )
Variables ¶
This section is empty.
Functions ¶
func ContextWithDBClient ¶
func ContextWithLogger ¶
func ContextWithOriginalPath ¶
func ContextWithResourceID ¶
func ContextWithSystemData ¶
func ContextWithVersion ¶
func ConvertCStoHCPOpenShiftCluster ¶
func ConvertCStoHCPOpenShiftCluster(resourceID *azcorearm.ResourceID, cluster *cmv1.Cluster) *api.HCPOpenShiftCluster
ConvertCStoHCPOpenShiftCluster converts a CS Cluster object into HCPOpenShiftCluster object
func ConvertCStoNodePool ¶
func ConvertCStoNodePool(resourceID *azcorearm.ResourceID, np *cmv1.NodePool) *api.HCPOpenShiftClusterNodePool
ConvertCStoNodePool converts a CS Node Pool object into HCPOpenShiftClusterNodePool object
func CorrelationDataFromContext ¶
func CorrelationDataFromContext(ctx context.Context) (*arm.CorrelationData, error)
func MiddlewareBody ¶
func MiddlewareBody(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)
func MiddlewareLockSubscription ¶
func MiddlewareLockSubscription(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)
func MiddlewareLogging ¶
func MiddlewareLogging(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)
func MiddlewareLoggingPostMux ¶
func MiddlewareLoggingPostMux(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)
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 MiddlewareResourceID ¶
func MiddlewareResourceID(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)
func MiddlewareSystemData ¶
func MiddlewareSystemData(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)
func MiddlewareValidateAPIVersion ¶
func MiddlewareValidateAPIVersion(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)
func MiddlewareValidateStatic ¶
func MiddlewareValidateStatic(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)
func MiddlewareValidateSubscriptionState ¶
func MiddlewareValidateSubscriptionState(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)
MiddlewareValidateSubscriptionState validates the state of the subscription as outlined by https://github.com/cloud-and-ai-microsoft/resource-provider-contract/blob/master/v1.0/subscription-lifecycle-api-reference.md
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 ResourceIDFromContext ¶
func ResourceIDFromContext(ctx context.Context) (*azcorearm.ResourceID, error)
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 Emitter ¶
type Emitter interface { AddCounter(metricName string, value float64, labels map[string]string) EmitGauge(metricName string, value float64, labels map[string]string) }
Emitter emits different types of metrics
type Frontend ¶
type Frontend struct {
// contains filtered or unexported fields
}
func NewFrontend ¶
func (*Frontend) AddAsyncOperationHeader ¶
func (f *Frontend) AddAsyncOperationHeader(writer http.ResponseWriter, request *http.Request, doc *database.OperationDocument)
AddAsyncOperationHeader adds an "Azure-AsyncOperation" header to the ResponseWriter with a URL of the operation status endpoint for the given OperationDocument.
func (*Frontend) AddLocationHeader ¶
func (f *Frontend) AddLocationHeader(writer http.ResponseWriter, request *http.Request, doc *database.OperationDocument)
AddLocationHeader adds a "Location" header to the ResponseWriter with a URL of the operation result endpoint for the given OperationDocument.
func (*Frontend) ArmDeploymentPreflight ¶
func (f *Frontend) ArmDeploymentPreflight(writer http.ResponseWriter, request *http.Request)
func (*Frontend) ArmResourceAction ¶
func (f *Frontend) ArmResourceAction(writer http.ResponseWriter, request *http.Request)
func (*Frontend) ArmResourceCreateOrUpdate ¶
func (f *Frontend) ArmResourceCreateOrUpdate(writer http.ResponseWriter, request *http.Request)
func (*Frontend) ArmResourceDelete ¶
func (f *Frontend) ArmResourceDelete(writer http.ResponseWriter, request *http.Request)
ArmResourceDelete 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) ArmResourceList ¶
func (f *Frontend) ArmResourceList(writer http.ResponseWriter, request *http.Request)
func (*Frontend) ArmResourceRead ¶
func (f *Frontend) ArmResourceRead(writer http.ResponseWriter, request *http.Request)
ArmResourceRead implements the GET single resource API contract for ARM * 200 If the resource exists * 404 If the resource does not exist
func (*Frontend) ArmSubscriptionGet ¶
func (f *Frontend) ArmSubscriptionGet(writer http.ResponseWriter, request *http.Request)
func (*Frontend) ArmSubscriptionPut ¶
func (f *Frontend) ArmSubscriptionPut(writer http.ResponseWriter, request *http.Request)
func (*Frontend) BuildCSCluster ¶
func (f *Frontend) BuildCSCluster(resourceID *azcorearm.ResourceID, requestHeader http.Header, hcpCluster *api.HCPOpenShiftCluster, updating bool) (*cmv1.Cluster, error)
BuildCSCluster creates a CS Cluster object from an HCPOpenShiftCluster object
func (*Frontend) BuildCSNodePool ¶
func (f *Frontend) BuildCSNodePool(ctx context.Context, nodePool *api.HCPOpenShiftClusterNodePool, updating bool) (*cmv1.NodePool, error)
BuildCSNodePool creates a CS Node Pool object from an HCPOpenShiftClusterNodePool object
func (*Frontend) CancelActiveOperation ¶
func (f *Frontend) CancelActiveOperation(ctx context.Context, resourceDoc *database.ResourceDocument) error
CancelActiveOperation marks the status of any active operation on the resource as canceled.
func (*Frontend) CheckForProvisioningStateConflict ¶
func (f *Frontend) CheckForProvisioningStateConflict(ctx context.Context, operationRequest database.OperationRequest, doc *database.ResourceDocument) *arm.CloudError
CheckForProvisioningStateConflict returns a "409 Conflict" error response if the provisioning state of the resource is non-terminal, or any of its parent resources within the same provider namespace are in a "Deleting" state.
func (*Frontend) CreateOrUpdateNodePool ¶
func (f *Frontend) CreateOrUpdateNodePool(writer http.ResponseWriter, request *http.Request)
func (*Frontend) DeleteAllResources ¶
func (*Frontend) DeleteResource ¶
func (f *Frontend) DeleteResource(ctx context.Context, resourceDoc *database.ResourceDocument) (string, *arm.CloudError)
func (*Frontend) ExposeOperation ¶
func (f *Frontend) ExposeOperation(writer http.ResponseWriter, request *http.Request, operationID string) error
ExposeOperation fully initiates a new asynchronous operation by enriching the operation database item and adding the necessary response headers.
func (*Frontend) Healthz ¶
func (f *Frontend) Healthz(writer http.ResponseWriter, request *http.Request)
func (*Frontend) MarshalResource ¶
func (f *Frontend) MarshalResource(ctx context.Context, resourceID *azcorearm.ResourceID, versionedInterface api.Version) ([]byte, *arm.CloudError)
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 (f *Frontend) OperationResult(writer http.ResponseWriter, request *http.Request)
func (*Frontend) OperationStatus ¶
func (f *Frontend) OperationStatus(writer http.ResponseWriter, request *http.Request)
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 { Emitter // contains filtered or unexported fields }
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 PrometheusEmitter ¶
type PrometheusEmitter struct {
// contains filtered or unexported fields
}
func NewPrometheusEmitter ¶
func NewPrometheusEmitter(r prometheus.Registerer) *PrometheusEmitter
func (*PrometheusEmitter) AddCounter ¶
func (pe *PrometheusEmitter) AddCounter(name string, value float64, labels map[string]string)
Source Files
¶
- const.go
- context.go
- frontend.go
- helpers.go
- metrics.go
- middleware.go
- middleware_body.go
- middleware_locksubscription.go
- middleware_logging.go
- middleware_lowercase.go
- middleware_panic.go
- middleware_resourceid.go
- middleware_systemdata.go
- middleware_validateapi.go
- middleware_validatestatic.go
- middleware_validatesubscription.go
- node_pool.go
- ocm.go
- operations.go
- routes.go