Documentation ¶
Overview ¶
Package dynamic provides the types and underlying implementation required to build virtual workspaces which can dynamically serve resources, based on API definitions (including an OpenAPI v3 schema), and a Rest storage provider.
Main idea ¶
APIs served by the virtual workspace are partitioned in API domains. Each API domain is defined by an api domain key and will expose a set of APIs that will be served at a dedicated URL path. API domain key is generally extracted from the URL sub-path where related APIs will be exposed.
APIs are served by an apiserver.DynamicAPIServer which is setup in the virtual workspace Register() method.
Typical operation ¶
The RootPathResolver() method would usually interpret the URL sub-path, extract the API domain key from it, and pass the request to the apiserver.DynamicAPIServer, along with the API domain key, if the API domain key contains APIs.
The BootstrapAPISetManagement() method would typically create and initialize an apidefinition.APIDefinitionSetGetter, returned as a result, and setup some logic that will call the apiserver.CreateServingInfoFor() method to add an APIDefinition in the APIDefinitionSetGetter on some event.
The apidefinition.APIDefinitionSetGetter returned by the BootstrapAPISetManagement() method is passed to the apiserver.DynamicAPIServer during the Register() call. The apiserver.DyncamicAPIServer uses it to correctly choose the appropriate apidefinition.APIDefinition used to serve the request, based on the context api domain key and the requested API GVR.
Example ¶
Typical Usage of a DynamicVirtualWorkspace
package main import ( "context" "errors" "github.com/kcp-dev/logicalcluster" genericapiserver "k8s.io/apiserver/pkg/server" apisv1alpha1 "github.com/kcp-dev/kcp/pkg/apis/apis/v1alpha1" virtualframework "github.com/kcp-dev/kcp/pkg/virtual/framework" "github.com/kcp-dev/kcp/pkg/virtual/framework/dynamic" "github.com/kcp-dev/kcp/pkg/virtual/framework/dynamic/apidefinition" "github.com/kcp-dev/kcp/pkg/virtual/framework/dynamic/apiserver" dynamiccontext "github.com/kcp-dev/kcp/pkg/virtual/framework/dynamic/context" ) // Typical Usage of a DynamicVirtualWorkspace func main() { var someAPIDefinitionSetGetter apidefinition.APIDefinitionSetGetter readyCh := make(chan struct{}) var _ = dynamic.DynamicVirtualWorkspace{ RootPathResolver: virtualframework.RootPathResolverFunc(func(urlPath string, requestContext context.Context) (accepted bool, prefixToStrip string, completedContext context.Context) { if someAPIDefinitionSetGetter == nil { // If the APIDefinitionSetGetter is not initialized, don't accept the request return } var apiDomainKey dynamiccontext.APIDomainKey // Resolve the request root path and extract the API domain key from it // If the root path doesn't start by the right prefix or doesn't contain the API domain key, // just don't accept the request and return. // Add the apiDomainKey to the request context before passing the request to the virtual workspace APIServer completedContext = dynamiccontext.WithAPIDomainKey(requestContext, apiDomainKey) accepted = true return }), ReadyChecker: virtualframework.ReadyFunc(func() error { select { case <-readyCh: return nil default: return errors.New("syncer virtual workspace controllers are not started") } }), BootstrapAPISetManagement: func(mainConfig genericapiserver.CompletedConfig) (apidefinition.APIDefinitionSetGetter, error) { // Initialize the implementation of the APIDefinitionSetGetter someAPIDefinitionSetGetter = newAPIDefinitionSetGetter() // Setup some controller that will add APIDefinitions on demand someController := setupController(func(logicalClusterName logicalcluster.Name, apiResourceSchema *apisv1alpha1.APIResourceSchema, version string) (apidefinition.APIDefinition, error) { // apiserver.CreateServingInfoFor() creates and initializes all the required information to serve an API return apiserver.CreateServingInfoFor(mainConfig, apiResourceSchema, version, someRestProviderFunc) }) // Start the controllers in a PostStartHook if err := mainConfig.AddPostStartHook("SomeDynamicVirtualWorkspacePostStartHook", func(hookContext genericapiserver.PostStartHookContext) error { // Wait for required informers to be synced someController.Start() close(readyCh) return nil }); err != nil { return nil, err } return someAPIDefinitionSetGetter, nil }, } } func newAPIDefinitionSetGetter() apidefinition.APIDefinitionSetGetter { return nil } type someController interface { Start() } // CreateAPIDefinitionFunc is the type of a function which allows creating an APIDefinition // (with REST storage and handler Request scopes) based on the API specification logical cluster name and OpenAPI v3 schema. type CreateAPIDefinitionFunc func(logicalClusterName logicalcluster.Name, apiResourceSchema *apisv1alpha1.APIResourceSchema, version string) (apidefinition.APIDefinition, error) func setupController(createAPIDefinition CreateAPIDefinitionFunc) someController { return nil } var someRestProviderFunc apiserver.RestProviderFunc
Output:
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type DynamicVirtualWorkspace ¶
type DynamicVirtualWorkspace struct { framework.RootPathResolver authorizer.Authorizer framework.ReadyChecker // BootstrapAPISetManagement creates, initializes and returns an apidefinition.APIDefinitionSetGetter. // Usually it would also set up some logic that will call the apiserver.CreateServingInfoFor() method // to add an apidefinition.APIDefinition in the apidefinition.APIDefinitionSetGetter on some event. BootstrapAPISetManagement func(mainConfig genericapiserver.CompletedConfig) (apidefinition.APIDefinitionSetGetter, error) }
DynamicVirtualWorkspace is an implementation of a framework.VirtualWorkspace which can dynamically serve resources, based on API definitions (including an OpenAPI v3 schema), and a Rest storage provider.
func (*DynamicVirtualWorkspace) Register ¶
func (vw *DynamicVirtualWorkspace) Register(vwName string, rootAPIServerConfig genericapiserver.CompletedConfig, delegateAPIServer genericapiserver.DelegationTarget) (genericapiserver.DelegationTarget, error)
Register builds and returns a DynamicAPIServer which will serve APIs whose serving informations are provided by an APISetRetriever. The APISetRetriever is returned by the virtual workspace BootstrapAPISetManagement function.
Directories ¶
Path | Synopsis |
---|---|
Package apiserver provides an APIServer that can dynamically serve resources based on an API definition (CommonAPIResourceSpec) source and a Rest storage provider.
|
Package apiserver provides an APIServer that can dynamically serve resources based on an API definition (CommonAPIResourceSpec) source and a Rest storage provider. |