dynamic

package
v0.5.0-alpha.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 1, 2022 License: Apache-2.0 Imports: 5 Imported by: 2

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"
	"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{

		Name: "SomeDynamicVirtualWorkspace",

		RootPathResolver: 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
		},

		Ready: 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 {
	Name             string
	RootPathResolver framework.RootPathResolverFunc
	Ready            framework.ReadyFunc

	// 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) GetName

func (vw *DynamicVirtualWorkspace) GetName() string

func (*DynamicVirtualWorkspace) IsReady

func (vw *DynamicVirtualWorkspace) IsReady() error

func (*DynamicVirtualWorkspace) Register

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.

func (*DynamicVirtualWorkspace) ResolveRootPath

func (vw *DynamicVirtualWorkspace) ResolveRootPath(urlPath string, context context.Context) (accepted bool, prefixToStrip string, completedContext context.Context)

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL