Skip to content

Commit cffe509

Browse files
committed
feat: add onex-apiserver code chassis
1 parent 666b490 commit cffe509

File tree

42 files changed

+406
-129
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+406
-129
lines changed

OWNERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# See the OWNERS docs at https://go.k8s.io/owners
1+
KubeVersionedInformers# See the OWNERS docs at https://go.k8s.io/owners
22

33
reviewers:
44
- colin404

cmd/onex-apiserver/apiserver.go

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,76 @@
99
package main
1010

1111
import (
12+
"context"
1213
"os"
1314

1415
_ "go.uber.org/automaxprocs/maxprocs"
16+
apierrors "k8s.io/apimachinery/pkg/api/errors"
17+
"k8s.io/apiserver/pkg/admission"
18+
genericapiserver "k8s.io/apiserver/pkg/server"
1519
"k8s.io/component-base/cli"
1620
_ "k8s.io/component-base/logs/json/register" // for JSON log format registration
1721
_ "k8s.io/component-base/metrics/prometheus/clientgo" // load all the prometheus client-go plugins
1822
_ "k8s.io/component-base/metrics/prometheus/version" // for version metric registration
23+
"k8s.io/klog/v2"
1924

2025
"github.com/superproj/onex/cmd/onex-apiserver/app"
26+
"github.com/superproj/onex/internal/apiserver/admission/plugin/minerset"
27+
"github.com/superproj/onex/internal/controlplane/admission/initializer"
28+
"github.com/superproj/onex/internal/pkg/config/minerprofile"
29+
//"github.com/superproj/onex/internal/pkg/options"
30+
appsrest "github.com/superproj/onex/internal/apiserver/registry/apps/rest"
31+
"github.com/superproj/onex/pkg/apis/apps/v1beta1"
32+
"github.com/superproj/onex/pkg/generated/clientset/versioned"
33+
"github.com/superproj/onex/pkg/generated/informers"
2134
)
2235

2336
func main() {
24-
command := app.NewAPIServerCommand()
37+
// Please note that the following WithOptions are all required.
38+
command := app.NewAPIServerCommand(
39+
// Add custom etcd options.
40+
app.WithEtcdOptions("/registry/onex.io", v1beta1.SchemeGroupVersion),
41+
// Add custom resource storage.
42+
app.WithRESTStorageProviders(appsrest.RESTStorageProvider{}),
43+
// Add custom dns address.
44+
app.WithAlternateDNS("onex.io"),
45+
// Add custom admission plugins.
46+
app.WithAdmissionPlugin(minerset.PluginName, minerset.Register),
47+
// Add custom admission plugins initializer.
48+
app.WithAdmissionInitializers(func(c *genericapiserver.RecommendedConfig) ([]admission.PluginInitializer, error) {
49+
client, err := versioned.NewForConfig(c.LoopbackClientConfig)
50+
if err != nil {
51+
return nil, err
52+
}
53+
informerFactory := informers.NewSharedInformerFactory(client, c.LoopbackClientConfig.Timeout)
54+
// NOTICE: As we create a shared informer, we need to start it later.
55+
app.WithSharedInformerFactory(informerFactory)
56+
return []admission.PluginInitializer{initializer.New(informerFactory, client)}, nil
57+
}),
58+
app.WithPostStartHook(
59+
"initialize-instance-config-client",
60+
func(ctx genericapiserver.PostStartHookContext) error {
61+
client, err := versioned.NewForConfig(ctx.LoopbackClientConfig)
62+
if err != nil {
63+
return err
64+
}
65+
66+
if err := minerprofile.Init(context.Background(), client); err != nil {
67+
// When returning 'NotFound' error, we should not report an error, otherwise we can not
68+
// create 'MinerTypesConfigMapName' configmap via onex-apiserver
69+
if apierrors.IsNotFound(err) {
70+
return nil
71+
}
72+
73+
klog.ErrorS(err, "Failed to init miner type cache")
74+
return err
75+
}
76+
77+
return nil
78+
},
79+
),
80+
)
81+
2582
code := cli.Run(command)
2683
os.Exit(code)
2784
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright 2022 Lingfei Kong <[email protected]>. All rights reserved.
2+
// Use of this source code is governed by a MIT style
3+
// license that can be found in the LICENSE file. The original repo for
4+
// this file is https://github.com/superproj/onex.
5+
//
6+
7+
package app
8+
9+
// UPDATEME: When add new api group.
10+
import (
11+
// These imports are the API groups the API server will support.
12+
_ "github.com/superproj/onex/pkg/apis/apps/install"
13+
)

cmd/onex-apiserver/app/options/options.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,14 @@
88
package options
99

1010
import (
11-
cliflag "k8s.io/component-base/cli/flag"
1211
"net"
1312

13+
genericapiserver "k8s.io/apiserver/pkg/server"
14+
cliflag "k8s.io/component-base/cli/flag"
15+
16+
"github.com/superproj/onex/internal/controlplane"
1417
controlplaneoptions "github.com/superproj/onex/internal/controlplane/apiserver/options"
18+
"github.com/superproj/onex/internal/controlplane/storage"
1519
)
1620

1721
const defaultEtcdPathPrefix = "/registry/onex.io"
@@ -29,14 +33,20 @@ type Extra struct {
2933
// OnexletConfig onexletclient.OnexletClientConfig
3034
APIServerServiceIP net.IP
3135
EndpointReconcilerType string
36+
37+
// For external resources
38+
ExternalRESTStorageProviders []storage.RESTStorageProvider
39+
ExternalVersionedInformers controlplane.ExternalSharedInformerFactory
40+
ExternalPostStartHooks map[string]genericapiserver.PostStartHookFunc
3241
}
3342

3443
// NewServerRunOptions returns a new ServerRunOptions.
3544
func NewServerRunOptions() *ServerRunOptions {
3645
o := &ServerRunOptions{
3746
Options: controlplaneoptions.NewOptions(),
3847
Extra: Extra{
39-
MasterCount: 1,
48+
MasterCount: 1,
49+
ExternalPostStartHooks: make(map[string]genericapiserver.PostStartHookFunc),
4050
},
4151
}
4252

cmd/onex-apiserver/app/server.go

Lines changed: 88 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,15 @@ import (
2121
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
2222
extensionsapiserver "k8s.io/apiextensions-apiserver/pkg/apiserver"
2323
"k8s.io/apimachinery/pkg/runtime"
24+
"k8s.io/apimachinery/pkg/runtime/schema"
2425
utilerrors "k8s.io/apimachinery/pkg/util/errors"
2526
utilnet "k8s.io/apimachinery/pkg/util/net"
2627
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
28+
"k8s.io/apiserver/pkg/admission"
2729
genericapifilters "k8s.io/apiserver/pkg/endpoints/filters"
2830
genericapiserver "k8s.io/apiserver/pkg/server"
31+
genericoptions "k8s.io/apiserver/pkg/server/options"
32+
"k8s.io/apiserver/pkg/storage/storagebackend"
2933
utilfeature "k8s.io/apiserver/pkg/util/feature"
3034
"k8s.io/apiserver/pkg/util/notfoundhandler"
3135
"k8s.io/apiserver/pkg/util/webhook"
@@ -45,6 +49,7 @@ import (
4549
"github.com/superproj/onex/cmd/onex-apiserver/app/options"
4650
"github.com/superproj/onex/internal/controlplane"
4751
controlplaneapiserver "github.com/superproj/onex/internal/controlplane/apiserver"
52+
"github.com/superproj/onex/internal/controlplane/storage"
4853
generatedopenapi "github.com/superproj/onex/pkg/generated/openapi"
4954
"github.com/superproj/onex/pkg/version"
5055
)
@@ -55,9 +60,80 @@ func init() {
5560
utilruntime.Must(logsapi.AddFeatureGates(utilfeature.DefaultMutableFeatureGate))
5661
}
5762

63+
type Option func(*options.ServerRunOptions)
64+
type RegisterFunc func(plugins *admission.Plugins)
65+
66+
// WithLegacyCode returns an Option that sets the external group versions in the ServerRunOptions.
67+
func WithEtcdOptions(prefix string, versions ...schema.GroupVersion) Option {
68+
return func(s *options.ServerRunOptions) {
69+
codec := legacyscheme.Codecs.LegacyCodec(versions...)
70+
s.RecommendedOptions.Etcd = genericoptions.NewEtcdOptions(storagebackend.NewDefaultConfig(prefix, codec))
71+
// Note: DefaultStorageMediaType needs to be reset here.
72+
s.RecommendedOptions.Etcd.DefaultStorageMediaType = "application/vnd.kubernetes.protobuf"
73+
/*
74+
s.RecommendedOptions.Etcd.StorageConfig.EncodeVersioner = runtime.NewMultiGroupVersioner(
75+
v1beta1.SchemeGroupVersion,
76+
schema.GroupKind{Group: v1beta1.GroupName},
77+
)
78+
*/
79+
for _, version := range versions {
80+
controlplane.AddStableAPIGroupVersionsEnabledByDefault(version)
81+
}
82+
}
83+
}
84+
85+
// WithAdmissionPlugin returns an Option function that adds an admission plugin to the recommended plugin order list
86+
// and registers the plugin using the provided RegisterFunc in the ServerRunOptions.
87+
func WithAdmissionPlugin(name string, registerFunc RegisterFunc) Option {
88+
return func(s *options.ServerRunOptions) {
89+
// Note: Need to add this to the RecommendedPluginOrder list.
90+
s.RecommendedOptions.Admission.RecommendedPluginOrder = append(s.RecommendedOptions.Admission.RecommendedPluginOrder, name)
91+
registerFunc(s.RecommendedOptions.Admission.Plugins)
92+
}
93+
}
94+
95+
// WithAdmissionInitializers returns an Option function that sets the external admission initializers in the ServerRunOptions.
96+
func WithAdmissionInitializers(initializer func(c *genericapiserver.RecommendedConfig) ([]admission.PluginInitializer, error)) Option {
97+
return func(s *options.ServerRunOptions) {
98+
s.RecommendedOptions.ExternalAdmissionInitializers = initializer
99+
}
100+
}
101+
102+
// WithPostStartHook returns an Option function that sets the external post-start hook with the given name in the ServerRunOptions.
103+
func WithPostStartHook(name string, hook genericapiserver.PostStartHookFunc) Option {
104+
return func(s *options.ServerRunOptions) {
105+
s.ExternalPostStartHooks[name] = hook
106+
}
107+
}
108+
109+
// WithSharedInformerFactory returns an Option function that sets the external SharedInformerFactory in the ServerRunOptions.
110+
func WithSharedInformerFactory(informers controlplane.ExternalSharedInformerFactory) Option {
111+
return func(s *options.ServerRunOptions) {
112+
s.ExternalVersionedInformers = informers
113+
}
114+
}
115+
116+
// WithRESTStorageProviders returns an Option function that sets the external REST storage providers in the ServerRunOptions.
117+
func WithRESTStorageProviders(providers ...storage.RESTStorageProvider) Option {
118+
return func(s *options.ServerRunOptions) {
119+
s.ExternalRESTStorageProviders = providers
120+
}
121+
}
122+
123+
// WithAlternateDNS returns an Option function that sets the alternate DNS configurations in the ServerRunOptions.
124+
func WithAlternateDNS(dns ...string) Option {
125+
return func(s *options.ServerRunOptions) {
126+
s.AlternateDNS = dns
127+
}
128+
}
129+
58130
// NewAPIServerCommand creates a *cobra.Command object with default parameters.
59-
func NewAPIServerCommand() *cobra.Command {
131+
func NewAPIServerCommand(serverRunOptions ...Option) *cobra.Command {
60132
s := options.NewServerRunOptions()
133+
for _, opt := range serverRunOptions {
134+
opt(s)
135+
}
136+
61137
cmd := &cobra.Command{
62138
Use: appName,
63139
Short: "Launch a onex API server",
@@ -198,7 +274,7 @@ func CreateOneXAPIServerConfig(opts options.CompletedOptions) (
198274
) {
199275
proxyTransport := CreateProxyTransport()
200276

201-
genericConfig, _, kubeVersionedInformers, storageFactory, err := controlplaneapiserver.BuildGenericConfig(
277+
genericConfig, _, kubeSharedInformers, storageFactory, err := controlplaneapiserver.BuildGenericConfig(
202278
opts.CompletedOptions,
203279
[]*runtime.Scheme{legacyscheme.Scheme, extensionsapiserver.Scheme, aggregatorscheme.Scheme},
204280
generatedopenapi.GetOpenAPIDefinitions,
@@ -217,10 +293,15 @@ func CreateOneXAPIServerConfig(opts options.CompletedOptions) (
217293
EventTTL: opts.EventTTL,
218294
EnableLogsSupport: opts.EnableLogsHandler,
219295
ProxyTransport: proxyTransport,
220-
MasterCount: opts.MasterCount,
221-
VersionedInformers: opts.SharedInformerFactory,
296+
//ExternalGroupResources: opts.ExternalGroupResources,
297+
ExternalRESTStorageProviders: opts.ExternalRESTStorageProviders,
298+
MasterCount: opts.MasterCount,
299+
//VersionedInformers: opts.SharedInformerFactory,
222300
// Here we will use the config file of "onex" to create a client-go informers.
223-
KubeVersionedInformers: kubeVersionedInformers,
301+
KubeVersionedInformers: kubeSharedInformers,
302+
InternalVersionedInformers: opts.InternalVersionedInformers,
303+
ExternalVersionedInformers: opts.ExternalVersionedInformers,
304+
ExternalPostStartHooks: opts.ExternalPostStartHooks,
224305
},
225306
}
226307

@@ -232,7 +313,7 @@ func CreateOneXAPIServerConfig(opts options.CompletedOptions) (
232313
// build peer proxy config only if peer ca file exists
233314
if opts.PeerCAFile != "" {
234315
config.ExtraConfig.PeerProxy, err = controlplaneapiserver.BuildPeerProxy(
235-
kubeVersionedInformers,
316+
kubeSharedInformers,
236317
genericConfig.StorageVersionManager,
237318
opts.ProxyClientCertFile,
238319
opts.ProxyClientKeyFile,
@@ -268,7 +349,7 @@ func CreateOneXAPIServerConfig(opts options.CompletedOptions) (
268349
}
269350
*/
270351

271-
serviceResolver := buildServiceResolver(opts.EnableAggregatorRouting, genericConfig.LoopbackClientConfig.Host, kubeVersionedInformers)
352+
serviceResolver := buildServiceResolver(opts.EnableAggregatorRouting, genericConfig.LoopbackClientConfig.Host, kubeSharedInformers)
272353

273354
return config, serviceResolver, nil
274355
}

internal/apiserver/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# apiserver 目录
2+
3+
该目录存放 onex-apiserver 业务的逻辑,包括:
4+
- registry: CURD 逻辑
5+
- admission: 动态准入控制
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// Copyright 2022 Lingfei Kong <[email protected]>. All rights reserved.
2+
// Use of this source code is governed by a MIT style
3+
// license that can be found in the LICENSE file. The original repo for
4+
// this file is https://github.com/superproj/onex.
5+
//
6+
7+
package initializer // import "github.com/superproj/onex/internal/controlplane/admission/initializer"
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Copyright 2022 Lingfei Kong <[email protected]>. All rights reserved.
2+
// Use of this source code is governed by a MIT style
3+
// license that can be found in the LICENSE file. The original repo for
4+
// this file is https://github.com/superproj/onex.
5+
//
6+
7+
package initializer
8+
9+
import (
10+
"k8s.io/apiserver/pkg/admission"
11+
12+
clientset "github.com/superproj/onex/pkg/generated/clientset/versioned"
13+
"github.com/superproj/onex/pkg/generated/informers"
14+
)
15+
16+
type pluginInitializer struct {
17+
informers informers.SharedInformerFactory
18+
externalClient clientset.Interface
19+
//authorizer authorizer.Authorizer
20+
//featureGates featuregate.FeatureGate
21+
stopCh <-chan struct{}
22+
}
23+
24+
var _ admission.PluginInitializer = pluginInitializer{}
25+
26+
// New creates an instance of node admission plugins initializer.
27+
func New(
28+
informers informers.SharedInformerFactory,
29+
extClientset clientset.Interface,
30+
) pluginInitializer {
31+
return pluginInitializer{
32+
informers: informers,
33+
externalClient: extClientset,
34+
}
35+
}
36+
37+
// Initialize checks the initialization interfaces implemented by a plugin
38+
// and provide the appropriate initialization data.
39+
func (i pluginInitializer) Initialize(plugin admission.Interface) {
40+
if wants, ok := plugin.(WantsExternalInformerFactory); ok {
41+
wants.SetInternalInformerFactory(i.informers)
42+
}
43+
44+
if wants, ok := plugin.(WantsExternalClientSet); ok {
45+
wants.SetExternalClientSet(i.externalClient)
46+
}
47+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright 2022 Lingfei Kong <[email protected]>. All rights reserved.
2+
// Use of this source code is governed by a MIT style
3+
// license that can be found in the LICENSE file. The original repo for
4+
// this file is https://github.com/superproj/onex.
5+
//
6+
7+
package initializer
8+
9+
import (
10+
"k8s.io/apiserver/pkg/admission"
11+
12+
clientset "github.com/superproj/onex/pkg/generated/clientset/versioned"
13+
"github.com/superproj/onex/pkg/generated/informers"
14+
)
15+
16+
// WantsExternalInformerFactory defines a function which sets InformerFactory for admission plugins that need it.
17+
type WantsExternalInformerFactory interface {
18+
admission.InitializationValidator
19+
SetInternalInformerFactory(informers.SharedInformerFactory)
20+
}
21+
22+
// WantsExternalClientSet defines a function which sets external ClientSet for admission plugins that need it.
23+
type WantsExternalClientSet interface {
24+
admission.InitializationValidator
25+
SetExternalClientSet(clientset.Interface)
26+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// Copyright 2022 Lingfei Kong <[email protected]>. All rights reserved.
2+
// Use of this source code is governed by a MIT style
3+
// license that can be found in the LICENSE file. The original repo for
4+
// this file is https://github.com/superproj/onex.
5+
//
6+
7+
package plugin // import "github.com/superproj/onex/internal/controlplane/admission/plugin"

0 commit comments

Comments
 (0)