Skip to content

Commit

Permalink
Extract etcd options from genericapiserver.
Browse files Browse the repository at this point in the history
  • Loading branch information
mksalawa committed Aug 9, 2016
1 parent 899d98a commit a806351
Show file tree
Hide file tree
Showing 13 changed files with 179 additions and 91 deletions.
5 changes: 3 additions & 2 deletions cmd/hyperkube/federation-apiserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import (
// NewFederationAPIServer creates a new hyperkube Server object that includes the
// description and flags.
func NewFederationAPIServer() *Server {
s := genericoptions.NewServerRunOptions()
s := genericoptions.NewServerRunOptions().WithEtcdOptions()

hks := Server{
SimpleUsage: "federation-apiserver",
Expand All @@ -33,6 +33,7 @@ func NewFederationAPIServer() *Server {
return app.Run(s)
},
}
s.AddFlags(hks.Flags())
s.AddUniversalFlags(hks.Flags())
s.AddEtcdStorageFlags(hks.Flags())
return &hks
}
6 changes: 4 additions & 2 deletions cmd/kube-apiserver/app/options/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ type APIServer struct {
// NewAPIServer creates a new APIServer object with default parameters
func NewAPIServer() *APIServer {
s := APIServer{
ServerRunOptions: genericoptions.NewServerRunOptions(),
ServerRunOptions: genericoptions.NewServerRunOptions().WithEtcdOptions(),
EventTTL: 1 * time.Hour,
KubeletConfig: kubeletclient.KubeletClientConfig{
Port: ports.KubeletPort,
Expand All @@ -62,7 +62,9 @@ func NewAPIServer() *APIServer {
// AddFlags adds flags for a specific APIServer to the specified FlagSet
func (s *APIServer) AddFlags(fs *pflag.FlagSet) {
// Add the generic flags.
s.ServerRunOptions.AddFlags(fs)
s.ServerRunOptions.AddUniversalFlags(fs)
//Add etcd specific flags.
s.ServerRunOptions.AddEtcdStorageFlags(fs)
// Note: the weird ""+ in below lines seems to be the only way to get gofmt to
// arrange these text blocks sensibly. Grrr.

Expand Down
2 changes: 2 additions & 0 deletions cmd/kube-apiserver/app/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import (
"k8s.io/kubernetes/pkg/controller/framework/informers"
serviceaccountcontroller "k8s.io/kubernetes/pkg/controller/serviceaccount"
"k8s.io/kubernetes/pkg/genericapiserver"
genericvalidation "k8s.io/kubernetes/pkg/genericapiserver/validation"
kubeletclient "k8s.io/kubernetes/pkg/kubelet/client"
"k8s.io/kubernetes/pkg/master"
"k8s.io/kubernetes/pkg/registry/cachesize"
Expand Down Expand Up @@ -81,6 +82,7 @@ cluster's shared state through which all other components interact.`,

// Run runs the specified APIServer. This should never exit.
func Run(s *options.APIServer) error {
genericvalidation.VerifyEtcdServersList(s.ServerRunOptions)
genericapiserver.DefaultAndValidateRunOptions(s.ServerRunOptions)

capabilities.Initialize(capabilities.Capabilities{
Expand Down
6 changes: 4 additions & 2 deletions examples/apiserver/apiserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"k8s.io/kubernetes/pkg/apimachinery/registered"
"k8s.io/kubernetes/pkg/genericapiserver"
genericoptions "k8s.io/kubernetes/pkg/genericapiserver/options"
genericvalidation "k8s.io/kubernetes/pkg/genericapiserver/validation"
"k8s.io/kubernetes/pkg/storage/storagebackend"

// Install the testgroup API
Expand All @@ -51,7 +52,7 @@ func newStorageFactory() genericapiserver.StorageFactory {
}

func NewServerRunOptions() *genericoptions.ServerRunOptions {
serverOptions := genericoptions.NewServerRunOptions()
serverOptions := genericoptions.NewServerRunOptions().WithEtcdOptions()
serverOptions.InsecurePort = InsecurePort
return serverOptions
}
Expand All @@ -61,7 +62,8 @@ func Run(serverOptions *genericoptions.ServerRunOptions) error {
_, serviceClusterIPRange, _ := net.ParseCIDR("10.0.0.0/24")
serverOptions.ServiceClusterIPRange = *serviceClusterIPRange
serverOptions.StorageConfig.ServerList = []string{"http://127.0.0.1:4001"}
genericapiserver.ValidateRunOptions(serverOptions)
genericvalidation.ValidateRunOptions(serverOptions)
genericvalidation.VerifyEtcdServersList(serverOptions)
config := genericapiserver.NewConfig(serverOptions)
config.Serializer = api.Codecs
s, err := genericapiserver.New(config)
Expand Down
3 changes: 2 additions & 1 deletion examples/apiserver/server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ func main() {
serverRunOptions := apiserver.NewServerRunOptions()

// Parse command line flags.
serverRunOptions.AddFlags(pflag.CommandLine)
serverRunOptions.AddUniversalFlags(pflag.CommandLine)
serverRunOptions.AddEtcdStorageFlags(pflag.CommandLine)
flag.InitFlags()

if err := apiserver.Run(serverRunOptions); err != nil {
Expand Down
5 changes: 3 additions & 2 deletions federation/cmd/federation-apiserver/apiserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ import (
func main() {
rand.Seed(time.Now().UTC().UnixNano())

s := genericoptions.NewServerRunOptions()
s.AddFlags(pflag.CommandLine)
s := genericoptions.NewServerRunOptions().WithEtcdOptions()
s.AddUniversalFlags(pflag.CommandLine)
s.AddEtcdStorageFlags(pflag.CommandLine)

flag.InitFlags()
util.InitLogs()
Expand Down
7 changes: 5 additions & 2 deletions federation/cmd/federation-apiserver/app/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,17 @@ import (
"k8s.io/kubernetes/pkg/controller/framework/informers"
"k8s.io/kubernetes/pkg/genericapiserver"
genericoptions "k8s.io/kubernetes/pkg/genericapiserver/options"
genericvalidation "k8s.io/kubernetes/pkg/genericapiserver/validation"
"k8s.io/kubernetes/pkg/registry/cachesize"
"k8s.io/kubernetes/pkg/registry/generic"
"k8s.io/kubernetes/pkg/util/wait"
)

// NewAPIServerCommand creates a *cobra.Command object with default parameters
func NewAPIServerCommand() *cobra.Command {
s := genericoptions.NewServerRunOptions()
s.AddFlags(pflag.CommandLine)
s := genericoptions.NewServerRunOptions().WithEtcdOptions()
s.AddUniversalFlags(pflag.CommandLine)
s.AddEtcdStorageFlags(pflag.CommandLine)
cmd := &cobra.Command{
Use: "federation-apiserver",
Long: `The Kubernetes federation API server validates and configures data
Expand All @@ -59,6 +61,7 @@ cluster's shared state through which all other components interact.`,

// Run runs the specified APIServer. This should never exit.
func Run(s *genericoptions.ServerRunOptions) error {
genericvalidation.VerifyEtcdServersList(s)
genericapiserver.DefaultAndValidateRunOptions(s)

// TODO: register cluster federation resources here.
Expand Down
4 changes: 2 additions & 2 deletions federation/cmd/federation-apiserver/app/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import (
)

func TestLongRunningRequestRegexp(t *testing.T) {
regexp := regexp.MustCompile(options.NewServerRunOptions().LongRunningRequestRE)
regexp := regexp.MustCompile(options.NewServerRunOptions().WithEtcdOptions().LongRunningRequestRE)
dontMatch := []string{
"/api/v1/watch-namespace/",
"/api/v1/namespace-proxy/",
Expand Down Expand Up @@ -84,7 +84,7 @@ var groupVersions = []unversioned.GroupVersion{
}

func TestRun(t *testing.T) {
s := options.NewServerRunOptions()
s := options.NewServerRunOptions().WithEtcdOptions()
s.InsecurePort = insecurePort
_, ipNet, _ := net.ParseCIDR("10.10.10.0/24")
s.ServiceClusterIPRange = *ipNet
Expand Down
52 changes: 2 additions & 50 deletions pkg/genericapiserver/genericapiserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import (
"k8s.io/kubernetes/pkg/auth/handlers"
"k8s.io/kubernetes/pkg/cloudprovider"
"k8s.io/kubernetes/pkg/genericapiserver/options"
genericvalidation "k8s.io/kubernetes/pkg/genericapiserver/validation"
"k8s.io/kubernetes/pkg/registry/generic"
"k8s.io/kubernetes/pkg/registry/generic/registry"
ipallocator "k8s.io/kubernetes/pkg/registry/service/ipallocator"
Expand Down Expand Up @@ -536,17 +537,6 @@ func (s *GenericAPIServer) installGroupsDiscoveryHandler() {
})
}

// TODO: Longer term we should read this from some config store, rather than a flag.
func verifyClusterIPFlags(options *options.ServerRunOptions) {
if options.ServiceClusterIPRange.IP == nil {
glog.Fatal("No --service-cluster-ip-range specified")
}
var ones, bits = options.ServiceClusterIPRange.Mask.Size()
if bits-ones > 20 {
glog.Fatal("Specified --service-cluster-ip-range is too large")
}
}

func NewConfig(options *options.ServerRunOptions) *Config {
return &Config{
APIGroupPrefix: options.APIGroupPrefix,
Expand All @@ -570,46 +560,8 @@ func NewConfig(options *options.ServerRunOptions) *Config {
}
}

func verifyServiceNodePort(options *options.ServerRunOptions) {
if options.KubernetesServiceNodePort < 0 || options.KubernetesServiceNodePort > 65535 {
glog.Fatalf("--kubernetes-service-node-port %v must be between 0 and 65535, inclusive. If 0, the Kubernetes master service will be of type ClusterIP.", options.KubernetesServiceNodePort)
}

if options.KubernetesServiceNodePort > 0 && !options.ServiceNodePortRange.Contains(options.KubernetesServiceNodePort) {
glog.Fatalf("Kubernetes service port range %v doesn't contain %v", options.ServiceNodePortRange, (options.KubernetesServiceNodePort))
}
}

func verifyEtcdServersList(options *options.ServerRunOptions) {
if len(options.StorageConfig.ServerList) == 0 {
glog.Fatalf("--etcd-servers must be specified")
}
}

func verifySecureAndInsecurePort(options *options.ServerRunOptions) {
if options.SecurePort < 0 || options.SecurePort > 65535 {
glog.Fatalf("--secure-port %v must be between 0 and 65535, inclusive. 0 for turning off secure port.", options.SecurePort)
}

// TODO: Allow 0 to turn off insecure port.
if options.InsecurePort < 1 || options.InsecurePort > 65535 {
glog.Fatalf("--insecure-port %v must be between 1 and 65535, inclusive.", options.InsecurePort)
}

if options.SecurePort == options.InsecurePort {
glog.Fatalf("--secure-port and --insecure-port cannot use the same port.")
}
}

func ValidateRunOptions(options *options.ServerRunOptions) {
verifyClusterIPFlags(options)
verifyServiceNodePort(options)
verifyEtcdServersList(options)
verifySecureAndInsecurePort(options)
}

func DefaultAndValidateRunOptions(options *options.ServerRunOptions) {
ValidateRunOptions(options)
genericvalidation.ValidateRunOptions(options)

// If advertise-address is not specified, use bind-address. If bind-address
// is not usable (unset, 0.0.0.0, or loopback), we will use the host's default
Expand Down
51 changes: 51 additions & 0 deletions pkg/genericapiserver/options/etcd_options.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package options

import (
"github.com/spf13/pflag"
)

const (
DefaultEtcdPathPrefix = "/registry"
)

// AddEtcdFlags adds flags related to etcd storage for a specific APIServer to the specified FlagSet
func (s *ServerRunOptions) AddEtcdStorageFlags(fs *pflag.FlagSet) {

fs.StringSliceVar(&s.EtcdServersOverrides, "etcd-servers-overrides", s.EtcdServersOverrides, ""+
"Per-resource etcd servers overrides, comma separated. The individual override "+
"format: group/resource#servers, where servers are http://ip:port, semicolon separated.")

fs.StringSliceVar(&s.StorageConfig.ServerList, "etcd-servers", s.StorageConfig.ServerList,
"List of etcd servers to connect with (http://ip:port), comma separated.")

fs.StringVar(&s.StorageConfig.Prefix, "etcd-prefix", s.StorageConfig.Prefix,
"The prefix for all resource paths in etcd.")

fs.StringVar(&s.StorageConfig.KeyFile, "etcd-keyfile", s.StorageConfig.KeyFile,
"SSL key file used to secure etcd communication.")

fs.StringVar(&s.StorageConfig.CertFile, "etcd-certfile", s.StorageConfig.CertFile,
"SSL certification file used to secure etcd communication.")

fs.StringVar(&s.StorageConfig.CAFile, "etcd-cafile", s.StorageConfig.CAFile,
"SSL Certificate Authority file used to secure etcd communication.")

fs.BoolVar(&s.StorageConfig.Quorum, "etcd-quorum-read", s.StorageConfig.Quorum,
"If true, enable quorum read.")
}
37 changes: 9 additions & 28 deletions pkg/genericapiserver/options/server_run_options.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ import (
)

const (
DefaultEtcdPathPrefix = "/registry"
DefaultDeserializationCacheSize = 50000

// TODO: This can be tightened up. It still matches objects named watch or proxy.
Expand Down Expand Up @@ -119,10 +118,6 @@ func NewServerRunOptions() *ServerRunOptions {
CertDirectory: "/var/run/kubernetes",
DefaultStorageMediaType: "application/json",
DefaultStorageVersions: registered.AllPreferredGroupVersions(),
StorageConfig: storagebackend.Config{
Prefix: DefaultEtcdPathPrefix,
DeserializationCacheSize: DefaultDeserializationCacheSize,
},
DeleteCollectionWorkers: 1,
EnableLogsSupport: true,
EnableProfiling: true,
Expand All @@ -141,6 +136,14 @@ func NewServerRunOptions() *ServerRunOptions {
}
}

func (o *ServerRunOptions) WithEtcdOptions() *ServerRunOptions {
o.StorageConfig = storagebackend.Config{
Prefix: DefaultEtcdPathPrefix,
DeserializationCacheSize: DefaultDeserializationCacheSize,
}
return o
}

// StorageGroupsToEncodingVersion returns a map from group name to group version,
// computed from the s.DeprecatedStorageVersion and s.StorageVersions flags.
func (s *ServerRunOptions) StorageGroupsToEncodingVersion() (map[string]unversioned.GroupVersion, error) {
Expand Down Expand Up @@ -212,7 +215,7 @@ func (s *ServerRunOptions) NewSelfClient() (clientset.Interface, error) {
}

// AddFlags adds flags for a specific APIServer to the specified FlagSet
func (s *ServerRunOptions) AddFlags(fs *pflag.FlagSet) {
func (s *ServerRunOptions) AddUniversalFlags(fs *pflag.FlagSet) {
// Note: the weird ""+ in below lines seems to be the only way to get gofmt to
// arrange these text blocks sensibly. Grrr.

Expand Down Expand Up @@ -301,10 +304,6 @@ func (s *ServerRunOptions) AddFlags(fs *pflag.FlagSet) {
fs.BoolVar(&s.EnableWatchCache, "watch-cache", s.EnableWatchCache,
"Enable watch caching in the apiserver")

fs.StringSliceVar(&s.EtcdServersOverrides, "etcd-servers-overrides", s.EtcdServersOverrides, ""+
"Per-resource etcd servers overrides, comma separated. The individual override "+
"format: group/resource#servers, where servers are http://ip:port, semicolon separated.")

fs.IntVar(&s.TargetRAMMB, "target-ram-mb", s.TargetRAMMB,
"Memory limit for apiserver in MB (used to configure sizes of caches, etc.)")

Expand Down Expand Up @@ -405,24 +404,6 @@ func (s *ServerRunOptions) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&s.StorageConfig.Type, "storage-backend", s.StorageConfig.Type,
"The storage backend for persistence. Options: 'etcd2' (default), 'etcd3'.")

fs.StringSliceVar(&s.StorageConfig.ServerList, "etcd-servers", s.StorageConfig.ServerList,
"List of etcd servers to connect with (http://ip:port), comma separated.")

fs.StringVar(&s.StorageConfig.Prefix, "etcd-prefix", s.StorageConfig.Prefix,
"The prefix for all resource paths in etcd.")

fs.StringVar(&s.StorageConfig.KeyFile, "etcd-keyfile", s.StorageConfig.KeyFile,
"SSL key file used to secure etcd communication.")

fs.StringVar(&s.StorageConfig.CertFile, "etcd-certfile", s.StorageConfig.CertFile,
"SSL certification file used to secure etcd communication.")

fs.StringVar(&s.StorageConfig.CAFile, "etcd-cafile", s.StorageConfig.CAFile,
"SSL Certificate Authority file used to secure etcd communication.")

fs.BoolVar(&s.StorageConfig.Quorum, "etcd-quorum-read", s.StorageConfig.Quorum,
"If true, enable quorum read.")

fs.IntVar(&s.StorageConfig.DeserializationCacheSize, "deserialization-cache-size", s.StorageConfig.DeserializationCacheSize,
"Number of deserialized json objects to cache in memory.")

Expand Down
28 changes: 28 additions & 0 deletions pkg/genericapiserver/validation/etcd_validation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
Copyright 2014 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package validation

import (
"github.com/golang/glog"
"k8s.io/kubernetes/pkg/genericapiserver/options"
)

func VerifyEtcdServersList(options *options.ServerRunOptions) {
if len(options.StorageConfig.ServerList) == 0 {
glog.Fatalf("--etcd-servers must be specified")
}
}
Loading

0 comments on commit a806351

Please sign in to comment.