// NewStorage returns a NodeStorage object that will work against nodes. func NewStorage(optsGetter generic.RESTOptionsGetter, kubeletClientConfig client.KubeletClientConfig, proxyTransport http.RoundTripper) (*NodeStorage, error) { store := &genericregistry.Store{ NewFunc: func() runtime.Object { return &api.Node{} }, NewListFunc: func() runtime.Object { return &api.NodeList{} }, ObjectNameFunc: func(obj runtime.Object) (string, error) { return obj.(*api.Node).Name, nil }, PredicateFunc: node.MatchNode, QualifiedResource: api.Resource("nodes"), CreateStrategy: node.Strategy, UpdateStrategy: node.Strategy, DeleteStrategy: node.Strategy, ExportStrategy: node.Strategy, } options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: node.GetAttrs, TriggerFunc: node.NodeNameTriggerFunc} if err := store.CompleteWithOptions(options); err != nil { return nil, err } statusStore := *store statusStore.UpdateStrategy = node.StatusStrategy // Set up REST handlers nodeREST := &REST{Store: store, proxyTransport: proxyTransport} statusREST := &StatusREST{store: &statusStore} proxyREST := &noderest.ProxyREST{Store: store, ProxyTransport: proxyTransport} // Build a NodeGetter that looks up nodes using the REST handler nodeGetter := client.NodeGetterFunc(func(nodeName string, options metav1.GetOptions) (*v1.Node, error) { obj, err := nodeREST.Get(genericapirequest.NewContext(), nodeName, &options) if err != nil { return nil, err } node, ok := obj.(*api.Node) if !ok { return nil, fmt.Errorf("unexpected type %T", obj) } // TODO: Remove the conversion. Consider only return the NodeAddresses externalNode := &v1.Node{} err = v1.Convert_api_Node_To_v1_Node(node, externalNode, nil) if err != nil { return nil, fmt.Errorf("failed to convert to v1.Node: %v", err) } return externalNode, nil }) connectionInfoGetter, err := client.NewNodeConnectionInfoGetter(nodeGetter, kubeletClientConfig) if err != nil { return nil, err } nodeREST.connection = connectionInfoGetter proxyREST.Connection = connectionInfoGetter return &NodeStorage{ Node: nodeREST, Status: statusREST, Proxy: proxyREST, KubeletConnectionInfo: connectionInfoGetter, }, nil }
// NewStorage returns a NodeStorage object that will work against nodes. func NewStorage(opts generic.RESTOptions, kubeletClientConfig client.KubeletClientConfig, proxyTransport http.RoundTripper) (*NodeStorage, error) { prefix := "/" + opts.ResourcePrefix newListFunc := func() runtime.Object { return &api.NodeList{} } storageInterface, dFunc := opts.Decorator( opts.StorageConfig, cachesize.GetWatchCacheSizeByResource(cachesize.Nodes), &api.Node{}, prefix, node.Strategy, newListFunc, node.GetAttrs, node.NodeNameTriggerFunc) store := &genericregistry.Store{ NewFunc: func() runtime.Object { return &api.Node{} }, NewListFunc: newListFunc, KeyRootFunc: func(ctx api.Context) string { return prefix }, KeyFunc: func(ctx api.Context, name string) (string, error) { return genericregistry.NoNamespaceKeyFunc(ctx, prefix, name) }, ObjectNameFunc: func(obj runtime.Object) (string, error) { return obj.(*api.Node).Name, nil }, PredicateFunc: node.MatchNode, QualifiedResource: api.Resource("nodes"), EnableGarbageCollection: opts.EnableGarbageCollection, DeleteCollectionWorkers: opts.DeleteCollectionWorkers, CreateStrategy: node.Strategy, UpdateStrategy: node.Strategy, DeleteStrategy: node.Strategy, ExportStrategy: node.Strategy, Storage: storageInterface, DestroyFunc: dFunc, } statusStore := *store statusStore.UpdateStrategy = node.StatusStrategy // Set up REST handlers nodeREST := &REST{Store: store, proxyTransport: proxyTransport} statusREST := &StatusREST{store: &statusStore} proxyREST := &noderest.ProxyREST{Store: store, ProxyTransport: proxyTransport} // Build a NodeGetter that looks up nodes using the REST handler nodeGetter := client.NodeGetterFunc(func(nodeName string) (*v1.Node, error) { obj, err := nodeREST.Get(api.NewContext(), nodeName, &metav1.GetOptions{}) if err != nil { return nil, err } node, ok := obj.(*api.Node) if !ok { return nil, fmt.Errorf("unexpected type %T", obj) } // TODO: Remove the conversion. Consider only return the NodeAddresses externalNode := &v1.Node{} err = v1.Convert_api_Node_To_v1_Node(node, externalNode, nil) if err != nil { return nil, fmt.Errorf("failed to convert to v1.Node: %v", err) } return externalNode, nil }) connectionInfoGetter, err := client.NewNodeConnectionInfoGetter(nodeGetter, kubeletClientConfig) if err != nil { return nil, err } nodeREST.connection = connectionInfoGetter proxyREST.Connection = connectionInfoGetter return &NodeStorage{ Node: nodeREST, Status: statusREST, Proxy: proxyREST, KubeletConnectionInfo: connectionInfoGetter, }, nil }
func addVersionsToScheme(externalVersions ...unversioned.GroupVersion) { // add the internal version to Scheme api.AddToScheme(api.Scheme) // add the enabled external versions to Scheme for _, v := range externalVersions { if !registered.IsEnabledVersion(v) { glog.Errorf("Version %s is not enabled, so it will not be added to the Scheme.", v) continue } switch v { case v1.SchemeGroupVersion: v1.AddToScheme(api.Scheme) case v1beta3.SchemeGroupVersion: v1beta3.AddToScheme(api.Scheme) } } // This is a "fast-path" that avoids reflection for common types. It focuses on the objects that are // converted the most in the cluster. // TODO: generate one of these for every external API group - this is to prove the impact api.Scheme.AddGenericConversionFunc(func(objA, objB interface{}, s conversion.Scope) (bool, error) { switch a := objA.(type) { case *v1.Pod: switch b := objB.(type) { case *api.Pod: return true, v1.Convert_v1_Pod_To_api_Pod(a, b, s) } case *api.Pod: switch b := objB.(type) { case *v1.Pod: return true, v1.Convert_api_Pod_To_v1_Pod(a, b, s) } case *v1.Event: switch b := objB.(type) { case *api.Event: return true, v1.Convert_v1_Event_To_api_Event(a, b, s) } case *api.Event: switch b := objB.(type) { case *v1.Event: return true, v1.Convert_api_Event_To_v1_Event(a, b, s) } case *v1.ReplicationController: switch b := objB.(type) { case *api.ReplicationController: return true, v1.Convert_v1_ReplicationController_To_api_ReplicationController(a, b, s) } case *api.ReplicationController: switch b := objB.(type) { case *v1.ReplicationController: return true, v1.Convert_api_ReplicationController_To_v1_ReplicationController(a, b, s) } case *v1.Node: switch b := objB.(type) { case *api.Node: return true, v1.Convert_v1_Node_To_api_Node(a, b, s) } case *api.Node: switch b := objB.(type) { case *v1.Node: return true, v1.Convert_api_Node_To_v1_Node(a, b, s) } case *v1.Namespace: switch b := objB.(type) { case *api.Namespace: return true, v1.Convert_v1_Namespace_To_api_Namespace(a, b, s) } case *api.Namespace: switch b := objB.(type) { case *v1.Namespace: return true, v1.Convert_api_Namespace_To_v1_Namespace(a, b, s) } case *v1.Service: switch b := objB.(type) { case *api.Service: return true, v1.Convert_v1_Service_To_api_Service(a, b, s) } case *api.Service: switch b := objB.(type) { case *v1.Service: return true, v1.Convert_api_Service_To_v1_Service(a, b, s) } case *v1.Endpoints: switch b := objB.(type) { case *api.Endpoints: return true, v1.Convert_v1_Endpoints_To_api_Endpoints(a, b, s) } case *api.Endpoints: switch b := objB.(type) { case *v1.Endpoints: return true, v1.Convert_api_Endpoints_To_v1_Endpoints(a, b, s) } } return false, nil }) }