1
16
17 package storage
18
19 import (
20 "context"
21 "fmt"
22 "net/http"
23 "net/url"
24
25 v1 "k8s.io/api/core/v1"
26 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
27 "k8s.io/apimachinery/pkg/runtime"
28 "k8s.io/apiserver/pkg/registry/generic"
29 genericregistry "k8s.io/apiserver/pkg/registry/generic/registry"
30 "k8s.io/apiserver/pkg/registry/rest"
31 api "k8s.io/kubernetes/pkg/apis/core"
32 k8s_api_v1 "k8s.io/kubernetes/pkg/apis/core/v1"
33 "k8s.io/kubernetes/pkg/kubelet/client"
34 "k8s.io/kubernetes/pkg/printers"
35 printersinternal "k8s.io/kubernetes/pkg/printers/internalversion"
36 printerstorage "k8s.io/kubernetes/pkg/printers/storage"
37 "k8s.io/kubernetes/pkg/registry/core/node"
38 noderest "k8s.io/kubernetes/pkg/registry/core/node/rest"
39 "sigs.k8s.io/structured-merge-diff/v4/fieldpath"
40 )
41
42
43 type NodeStorage struct {
44 Node *REST
45 Status *StatusREST
46 Proxy *noderest.ProxyREST
47
48 KubeletConnectionInfo client.ConnectionInfoGetter
49 }
50
51
52 type REST struct {
53 *genericregistry.Store
54 connection client.ConnectionInfoGetter
55 proxyTransport http.RoundTripper
56 }
57
58
59 type StatusREST struct {
60 store *genericregistry.Store
61 }
62
63
64 func (r *StatusREST) New() runtime.Object {
65 return &api.Node{}
66 }
67
68
69 func (r *StatusREST) Destroy() {
70
71
72 }
73
74
75 func (r *StatusREST) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) {
76 return r.store.Get(ctx, name, options)
77 }
78
79
80 func (r *StatusREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) {
81
82
83 return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false, options)
84 }
85
86
87 func (r *StatusREST) GetResetFields() map[fieldpath.APIVersion]*fieldpath.Set {
88 return r.store.GetResetFields()
89 }
90
91 func (r *StatusREST) ConvertToTable(ctx context.Context, object runtime.Object, tableOptions runtime.Object) (*metav1.Table, error) {
92 return r.store.ConvertToTable(ctx, object, tableOptions)
93 }
94
95
96 func NewStorage(optsGetter generic.RESTOptionsGetter, kubeletClientConfig client.KubeletClientConfig, proxyTransport http.RoundTripper) (*NodeStorage, error) {
97 store := &genericregistry.Store{
98 NewFunc: func() runtime.Object { return &api.Node{} },
99 NewListFunc: func() runtime.Object { return &api.NodeList{} },
100 PredicateFunc: node.MatchNode,
101 DefaultQualifiedResource: api.Resource("nodes"),
102 SingularQualifiedResource: api.Resource("node"),
103
104 CreateStrategy: node.Strategy,
105 UpdateStrategy: node.Strategy,
106 DeleteStrategy: node.Strategy,
107 ResetFieldsStrategy: node.Strategy,
108
109 TableConvertor: printerstorage.TableConvertor{TableGenerator: printers.NewTableGenerator().With(printersinternal.AddHandlers)},
110 }
111 options := &generic.StoreOptions{
112 RESTOptions: optsGetter,
113 AttrFunc: node.GetAttrs,
114 }
115 if err := store.CompleteWithOptions(options); err != nil {
116 return nil, err
117 }
118
119 statusStore := *store
120 statusStore.UpdateStrategy = node.StatusStrategy
121 statusStore.ResetFieldsStrategy = node.StatusStrategy
122
123
124 nodeREST := &REST{Store: store, proxyTransport: proxyTransport}
125 statusREST := &StatusREST{store: &statusStore}
126 proxyREST := &noderest.ProxyREST{Store: store, ProxyTransport: proxyTransport}
127
128
129 nodeGetter := client.NodeGetterFunc(func(ctx context.Context, nodeName string, options metav1.GetOptions) (*v1.Node, error) {
130 obj, err := nodeREST.Get(ctx, nodeName, &options)
131 if err != nil {
132 return nil, err
133 }
134 node, ok := obj.(*api.Node)
135 if !ok {
136 return nil, fmt.Errorf("unexpected type %T", obj)
137 }
138
139 externalNode := &v1.Node{}
140 err = k8s_api_v1.Convert_core_Node_To_v1_Node(node, externalNode, nil)
141 if err != nil {
142 return nil, fmt.Errorf("failed to convert to v1.Node: %v", err)
143 }
144 return externalNode, nil
145 })
146 connectionInfoGetter, err := client.NewNodeConnectionInfoGetter(nodeGetter, kubeletClientConfig)
147 if err != nil {
148 return nil, err
149 }
150 nodeREST.connection = connectionInfoGetter
151 proxyREST.Connection = connectionInfoGetter
152
153 return &NodeStorage{
154 Node: nodeREST,
155 Status: statusREST,
156 Proxy: proxyREST,
157 KubeletConnectionInfo: connectionInfoGetter,
158 }, nil
159 }
160
161
162 var _ = rest.Redirector(&REST{})
163
164
165 func (r *REST) ResourceLocation(ctx context.Context, id string) (*url.URL, http.RoundTripper, error) {
166 return node.ResourceLocation(r, r.connection, r.proxyTransport, ctx, id)
167 }
168
169
170 func (r *REST) ShortNames() []string {
171 return []string{"no"}
172 }
173
View as plain text