...
1
16
17 package server
18
19 import (
20 "errors"
21 "fmt"
22 "io"
23
24 "github.com/spf13/cobra"
25 "github.com/spf13/pflag"
26 openapinamer "k8s.io/apiserver/pkg/endpoints/openapi"
27
28 utilerrors "k8s.io/apimachinery/pkg/util/errors"
29 "k8s.io/apimachinery/pkg/util/sets"
30 genericapiserver "k8s.io/apiserver/pkg/server"
31 "k8s.io/apiserver/pkg/server/filters"
32 genericoptions "k8s.io/apiserver/pkg/server/options"
33 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1beta1"
34 "k8s.io/kube-aggregator/pkg/apiserver"
35 aggregatorscheme "k8s.io/kube-aggregator/pkg/apiserver/scheme"
36 "k8s.io/kube-aggregator/pkg/generated/openapi"
37 )
38
39 const defaultEtcdPathPrefix = "/registry/kube-aggregator.kubernetes.io/"
40
41
42 type AggregatorOptions struct {
43 ServerRunOptions *genericoptions.ServerRunOptions
44 RecommendedOptions *genericoptions.RecommendedOptions
45 APIEnablement *genericoptions.APIEnablementOptions
46
47
48
49 ProxyClientCertFile string
50 ProxyClientKeyFile string
51
52 StdOut io.Writer
53 StdErr io.Writer
54 }
55
56
57
58 func NewCommandStartAggregator(defaults *AggregatorOptions, stopCh <-chan struct{}) *cobra.Command {
59 o := *defaults
60 cmd := &cobra.Command{
61 Short: "Launch a API aggregator and proxy server",
62 Long: "Launch a API aggregator and proxy server",
63 RunE: func(c *cobra.Command, args []string) error {
64 if err := o.Complete(); err != nil {
65 return err
66 }
67 if err := o.Validate(args); err != nil {
68 return err
69 }
70 if err := o.RunAggregator(stopCh); err != nil {
71 return err
72 }
73 return nil
74 },
75 }
76
77 o.AddFlags(cmd.Flags())
78 return cmd
79 }
80
81
82 func (o *AggregatorOptions) AddFlags(fs *pflag.FlagSet) {
83 o.ServerRunOptions.AddUniversalFlags(fs)
84 o.RecommendedOptions.AddFlags(fs)
85 o.APIEnablement.AddFlags(fs)
86 fs.StringVar(&o.ProxyClientCertFile, "proxy-client-cert-file", o.ProxyClientCertFile, "client certificate used identify the proxy to the API server")
87 fs.StringVar(&o.ProxyClientKeyFile, "proxy-client-key-file", o.ProxyClientKeyFile, "client certificate key used identify the proxy to the API server")
88 }
89
90
91 func NewDefaultOptions(out, err io.Writer) *AggregatorOptions {
92 o := &AggregatorOptions{
93 ServerRunOptions: genericoptions.NewServerRunOptions(),
94 RecommendedOptions: genericoptions.NewRecommendedOptions(
95 defaultEtcdPathPrefix,
96 aggregatorscheme.Codecs.LegacyCodec(v1beta1.SchemeGroupVersion),
97 ),
98 APIEnablement: genericoptions.NewAPIEnablementOptions(),
99
100 StdOut: out,
101 StdErr: err,
102 }
103
104 return o
105 }
106
107
108 func (o AggregatorOptions) Validate(args []string) error {
109 errors := []error{}
110 errors = append(errors, o.ServerRunOptions.Validate()...)
111 errors = append(errors, o.RecommendedOptions.Validate()...)
112 errors = append(errors, o.APIEnablement.Validate(aggregatorscheme.Scheme)...)
113 return utilerrors.NewAggregate(errors)
114 }
115
116
117 func (o *AggregatorOptions) Complete() error {
118 return nil
119 }
120
121
122 func (o AggregatorOptions) RunAggregator(stopCh <-chan struct{}) error {
123
124 if err := o.RecommendedOptions.SecureServing.MaybeDefaultWithSelfSignedCerts("localhost", nil, nil); err != nil {
125 return fmt.Errorf("error creating self-signed certificates: %v", err)
126 }
127
128 serverConfig := genericapiserver.NewRecommendedConfig(aggregatorscheme.Codecs)
129
130 if err := o.ServerRunOptions.ApplyTo(&serverConfig.Config); err != nil {
131 return err
132 }
133 if err := o.RecommendedOptions.ApplyTo(serverConfig); err != nil {
134 return err
135 }
136 if err := o.APIEnablement.ApplyTo(&serverConfig.Config, apiserver.DefaultAPIResourceConfigSource(), aggregatorscheme.Scheme); err != nil {
137 return err
138 }
139 serverConfig.LongRunningFunc = filters.BasicLongRunningRequestCheck(
140 sets.NewString("watch", "proxy"),
141 sets.NewString("attach", "exec", "proxy", "log", "portforward"),
142 )
143 serverConfig.OpenAPIConfig = genericapiserver.DefaultOpenAPIConfig(openapi.GetOpenAPIDefinitions, openapinamer.NewDefinitionNamer(aggregatorscheme.Scheme))
144 serverConfig.OpenAPIConfig.Info.Title = "kube-aggregator"
145
146
147 serverConfig.SkipOpenAPIInstallation = true
148
149 serviceResolver := apiserver.NewClusterIPServiceResolver(serverConfig.SharedInformerFactory.Core().V1().Services().Lister())
150
151 config := apiserver.Config{
152 GenericConfig: serverConfig,
153 ExtraConfig: apiserver.ExtraConfig{
154 ServiceResolver: serviceResolver,
155 },
156 }
157
158 if len(o.ProxyClientCertFile) == 0 || len(o.ProxyClientKeyFile) == 0 {
159 return errors.New("missing a client certificate along with a key to identify the proxy to the API server")
160 }
161
162 config.ExtraConfig.ProxyClientCertFile = o.ProxyClientCertFile
163 config.ExtraConfig.ProxyClientKeyFile = o.ProxyClientKeyFile
164
165 server, err := config.Complete().NewWithDelegate(genericapiserver.NewEmptyDelegate())
166 if err != nil {
167 return err
168 }
169
170 prepared, err := server.PrepareRun()
171 if err != nil {
172 return err
173 }
174 return prepared.Run(stopCh)
175 }
176
View as plain text