2015-01-30 17:04:39 +00:00
/ *
2016-06-03 00:25:58 +00:00
Copyright 2014 The Kubernetes Authors .
2015-01-30 17:04:39 +00:00
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 .
* /
2015-02-07 22:13:22 +00:00
// Package app does all of the work necessary to create a Kubernetes
2015-01-30 17:04:39 +00:00
// APIServer by binding together the API, master and APIServer infrastructure.
// It can be configured and called directly or via the hyperkube framework.
2015-02-07 22:13:22 +00:00
package app
2015-01-30 17:04:39 +00:00
import (
"crypto/tls"
2016-12-01 16:21:49 +00:00
"fmt"
2017-02-21 12:48:04 +00:00
"io/ioutil"
2015-01-30 17:04:39 +00:00
"net"
2016-10-17 19:16:58 +00:00
"net/http"
2015-12-05 02:01:29 +00:00
"net/url"
2016-12-13 08:22:48 +00:00
"os"
2017-03-15 15:26:37 +00:00
"reflect"
2015-01-30 17:04:39 +00:00
"strconv"
"strings"
2016-06-08 13:04:38 +00:00
"time"
2015-01-30 17:04:39 +00:00
2017-02-02 00:05:55 +00:00
"github.com/go-openapi/spec"
2015-12-25 00:08:15 +00:00
"github.com/golang/glog"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
2017-02-16 22:40:55 +00:00
"k8s.io/apimachinery/pkg/apis/meta/v1"
2017-01-11 14:09:48 +00:00
"k8s.io/apimachinery/pkg/runtime/schema"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
utilnet "k8s.io/apimachinery/pkg/util/net"
"k8s.io/apimachinery/pkg/util/sets"
2017-01-11 23:14:42 +00:00
utilwait "k8s.io/apimachinery/pkg/util/wait"
2017-01-17 21:42:13 +00:00
"k8s.io/apiserver/pkg/admission"
2017-10-26 21:19:49 +00:00
"k8s.io/apiserver/pkg/admission/plugin/webhook"
2017-03-15 15:26:37 +00:00
"k8s.io/apiserver/pkg/authentication/authenticator"
"k8s.io/apiserver/pkg/authorization/authorizer"
2017-02-02 09:25:56 +00:00
genericapiserver "k8s.io/apiserver/pkg/server"
2017-01-26 19:39:54 +00:00
"k8s.io/apiserver/pkg/server/filters"
2017-09-07 20:59:31 +00:00
serveroptions "k8s.io/apiserver/pkg/server/options"
2017-05-24 00:30:49 +00:00
"k8s.io/apiserver/pkg/server/options/encryptionconfig"
2017-02-11 11:26:43 +00:00
serverstorage "k8s.io/apiserver/pkg/server/storage"
2017-06-02 00:11:23 +00:00
aggregatorapiserver "k8s.io/kube-aggregator/pkg/apiserver"
2017-07-20 06:34:37 +00:00
openapi "k8s.io/kube-openapi/pkg/common"
2017-03-10 18:51:02 +00:00
2017-07-16 02:00:35 +00:00
"k8s.io/apiserver/pkg/storage/etcd3/preflight"
2017-06-02 00:11:23 +00:00
clientgoinformers "k8s.io/client-go/informers"
clientgoclientset "k8s.io/client-go/kubernetes"
2015-12-25 00:08:15 +00:00
"k8s.io/kubernetes/cmd/kube-apiserver/app/options"
2017-10-16 11:41:50 +00:00
"k8s.io/kubernetes/pkg/api/legacyscheme"
2017-01-10 16:25:32 +00:00
"k8s.io/kubernetes/pkg/apis/apps"
2016-02-17 17:11:31 +00:00
"k8s.io/kubernetes/pkg/apis/batch"
2017-01-10 16:25:32 +00:00
"k8s.io/kubernetes/pkg/apis/extensions"
2017-03-13 14:31:16 +00:00
"k8s.io/kubernetes/pkg/apis/networking"
2015-08-05 22:03:47 +00:00
"k8s.io/kubernetes/pkg/capabilities"
2016-11-09 18:53:23 +00:00
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
2017-02-15 19:00:29 +00:00
informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
2015-08-05 22:03:47 +00:00
"k8s.io/kubernetes/pkg/cloudprovider"
2015-12-24 21:54:40 +00:00
serviceaccountcontroller "k8s.io/kubernetes/pkg/controller/serviceaccount"
2016-10-08 09:36:37 +00:00
generatedopenapi "k8s.io/kubernetes/pkg/generated/openapi"
2017-01-16 12:00:22 +00:00
"k8s.io/kubernetes/pkg/kubeapiserver"
2017-03-27 11:26:03 +00:00
kubeapiserveradmission "k8s.io/kubernetes/pkg/kubeapiserver/admission"
2016-12-21 17:45:38 +00:00
kubeauthenticator "k8s.io/kubernetes/pkg/kubeapiserver/authenticator"
2017-03-31 01:40:51 +00:00
"k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes"
2017-03-09 18:51:59 +00:00
kubeoptions "k8s.io/kubernetes/pkg/kubeapiserver/options"
2017-03-09 19:39:56 +00:00
kubeserver "k8s.io/kubernetes/pkg/kubeapiserver/server"
2015-08-05 22:03:47 +00:00
"k8s.io/kubernetes/pkg/master"
2017-09-11 15:13:47 +00:00
"k8s.io/kubernetes/pkg/master/reconcilers"
2017-01-09 18:27:59 +00:00
"k8s.io/kubernetes/pkg/master/tunneler"
2017-05-18 18:00:02 +00:00
quotainstall "k8s.io/kubernetes/pkg/quota/install"
2016-02-05 07:47:27 +00:00
"k8s.io/kubernetes/pkg/registry/cachesize"
2017-03-31 01:40:51 +00:00
rbacrest "k8s.io/kubernetes/pkg/registry/rbac/rest"
2016-10-17 18:51:59 +00:00
"k8s.io/kubernetes/pkg/version"
2017-02-16 22:40:55 +00:00
"k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/bootstrap"
2017-06-28 20:30:23 +00:00
2017-10-18 16:57:59 +00:00
"k8s.io/client-go/rest"
2017-11-08 22:34:54 +00:00
api "k8s.io/kubernetes/pkg/apis/core"
2017-06-28 20:30:23 +00:00
_ "k8s.io/kubernetes/pkg/util/reflector/prometheus" // for reflector metric registration
_ "k8s.io/kubernetes/pkg/util/workqueue/prometheus" // for workqueue metric registration
2015-05-12 02:41:13 +00:00
)
2017-01-11 23:14:42 +00:00
const etcdRetryLimit = 60
const etcdRetryInterval = 1 * time . Second
2015-10-12 14:33:39 +00:00
// NewAPIServerCommand creates a *cobra.Command object with default parameters
func NewAPIServerCommand ( ) * cobra . Command {
2016-10-25 07:18:05 +00:00
s := options . NewServerRunOptions ( )
2015-10-12 14:33:39 +00:00
s . AddFlags ( pflag . CommandLine )
cmd := & cobra . Command {
Use : "kube-apiserver" ,
Long : ` The Kubernetes API server validates and configures data
for the api objects which include pods , services , replicationcontrollers , and
others . The API Server services REST operations and provides the frontend to the
cluster ' s shared state through which all other components interact . ` ,
Run : func ( cmd * cobra . Command , args [ ] string ) {
} ,
}
return cmd
}
2015-01-30 17:04:39 +00:00
// Run runs the specified APIServer. This should never exit.
2017-03-10 18:51:02 +00:00
func Run ( runOptions * options . ServerRunOptions , stopCh <- chan struct { } ) error {
2017-06-01 21:30:34 +00:00
// To help debugging, immediately log version
glog . Infof ( "Version: %+v" , version . Get ( ) )
2017-06-02 15:31:47 +00:00
server , err := CreateServerChain ( runOptions , stopCh )
2017-05-29 03:28:41 +00:00
if err != nil {
return err
}
2017-06-02 00:11:23 +00:00
2017-07-05 10:41:05 +00:00
return server . PrepareRun ( ) . Run ( stopCh )
}
2017-06-02 15:31:47 +00:00
// CreateServerChain creates the apiservers connected via delegation.
func CreateServerChain ( runOptions * options . ServerRunOptions , stopCh <- chan struct { } ) ( * genericapiserver . GenericAPIServer , error ) {
2017-07-05 10:41:05 +00:00
nodeTunneler , proxyTransport , err := CreateNodeDialer ( runOptions )
if err != nil {
return nil , err
}
2017-06-21 17:02:52 +00:00
kubeAPIServerConfig , sharedInformers , versionedInformers , insecureServingOptions , serviceResolver , err := CreateKubeAPIServerConfig ( runOptions , nodeTunneler , proxyTransport )
2017-03-10 18:51:02 +00:00
if err != nil {
2017-07-05 10:41:05 +00:00
return nil , err
2017-03-10 18:51:02 +00:00
}
2017-05-18 18:50:35 +00:00
2017-05-23 19:16:45 +00:00
// TPRs are enabled and not yet beta, since this these are the successor, they fall under the same enablement rule
// If additional API servers are added, they should be gated.
2017-09-06 16:22:23 +00:00
apiExtensionsConfig , err := createAPIExtensionsConfig ( * kubeAPIServerConfig . GenericConfig , versionedInformers , runOptions )
2017-05-23 19:16:45 +00:00
if err != nil {
2017-07-05 10:41:05 +00:00
return nil , err
2017-05-23 19:16:45 +00:00
}
apiExtensionsServer , err := createAPIExtensionsServer ( apiExtensionsConfig , genericapiserver . EmptyDelegate )
if err != nil {
2017-07-05 10:41:05 +00:00
return nil , err
2017-05-23 19:16:45 +00:00
}
2017-09-06 16:22:23 +00:00
kubeAPIServer , err := CreateKubeAPIServer ( kubeAPIServerConfig , apiExtensionsServer . GenericAPIServer , sharedInformers , versionedInformers )
2017-05-18 18:50:35 +00:00
if err != nil {
2017-07-05 10:41:05 +00:00
return nil , err
2017-05-18 18:50:35 +00:00
}
2017-05-18 20:55:35 +00:00
// if we're starting up a hacked up version of this API server for a weird test case,
// just start the API server as is because clients don't get built correctly when you do this
if len ( os . Getenv ( "KUBE_API_VERSIONS" ) ) > 0 {
if insecureServingOptions != nil {
insecureHandlerChain := kubeserver . BuildInsecureHandlerChain ( kubeAPIServer . GenericAPIServer . UnprotectedHandler ( ) , kubeAPIServerConfig . GenericConfig )
2017-11-02 11:29:31 +00:00
if err := kubeserver . NonBlockingRun ( insecureServingOptions , insecureHandlerChain , kubeAPIServerConfig . GenericConfig . RequestTimeout , stopCh ) ; err != nil {
2017-07-05 10:41:05 +00:00
return nil , err
2017-05-18 20:55:35 +00:00
}
}
2017-07-05 10:41:05 +00:00
return kubeAPIServer . GenericAPIServer , nil
2017-05-18 20:55:35 +00:00
}
// otherwise go down the normal path of standing the aggregator up in front of the API server
// this wires up openapi
kubeAPIServer . GenericAPIServer . PrepareRun ( )
2017-08-17 19:49:19 +00:00
// This will wire up openapi for extension api server
apiExtensionsServer . GenericAPIServer . PrepareRun ( )
2017-05-18 18:50:35 +00:00
// aggregator comes last in the chain
2017-06-21 17:02:52 +00:00
aggregatorConfig , err := createAggregatorConfig ( * kubeAPIServerConfig . GenericConfig , runOptions , versionedInformers , serviceResolver , proxyTransport )
2017-02-23 21:34:09 +00:00
if err != nil {
2017-07-05 10:41:05 +00:00
return nil , err
2017-02-23 21:34:09 +00:00
}
2017-09-06 15:46:05 +00:00
aggregatorConfig . ExtraConfig . ProxyTransport = proxyTransport
aggregatorConfig . ExtraConfig . ServiceResolver = serviceResolver
2017-06-27 20:40:14 +00:00
aggregatorServer , err := createAggregatorServer ( aggregatorConfig , kubeAPIServer . GenericAPIServer , apiExtensionsServer . Informers )
2017-03-10 18:51:02 +00:00
if err != nil {
2017-03-20 14:58:27 +00:00
// we don't need special handling for innerStopCh because the aggregator server doesn't create any go routines
2017-07-05 10:41:05 +00:00
return nil , err
2017-03-10 18:51:02 +00:00
}
2017-05-18 20:55:35 +00:00
if insecureServingOptions != nil {
insecureHandlerChain := kubeserver . BuildInsecureHandlerChain ( aggregatorServer . GenericAPIServer . UnprotectedHandler ( ) , kubeAPIServerConfig . GenericConfig )
2017-11-02 11:29:31 +00:00
if err := kubeserver . NonBlockingRun ( insecureServingOptions , insecureHandlerChain , kubeAPIServerConfig . GenericConfig . RequestTimeout , stopCh ) ; err != nil {
2017-07-05 10:41:05 +00:00
return nil , err
2017-05-18 20:55:35 +00:00
}
}
2017-07-05 10:41:05 +00:00
return aggregatorServer . GenericAPIServer , nil
2017-03-10 18:51:02 +00:00
}
// CreateKubeAPIServer creates and wires a workable kube-apiserver
2017-09-06 16:22:23 +00:00
func CreateKubeAPIServer ( kubeAPIServerConfig * master . Config , delegateAPIServer genericapiserver . DelegationTarget , sharedInformers informers . SharedInformerFactory , versionedInformers clientgoinformers . SharedInformerFactory ) ( * master . Master , error ) {
kubeAPIServer , err := kubeAPIServerConfig . Complete ( versionedInformers ) . New ( delegateAPIServer )
2017-03-10 18:51:02 +00:00
if err != nil {
return nil , err
}
kubeAPIServer . GenericAPIServer . AddPostStartHook ( "start-kube-apiserver-informers" , func ( context genericapiserver . PostStartHookContext ) error {
2017-05-08 15:05:28 +00:00
sharedInformers . Start ( context . StopCh )
2017-03-15 14:33:39 +00:00
return nil
} )
2017-02-23 21:34:09 +00:00
2017-03-10 18:51:02 +00:00
return kubeAPIServer , nil
2017-02-23 21:34:09 +00:00
}
2017-06-08 16:19:12 +00:00
// CreateNodeDialer creates the dialer infrastructure to connect to the nodes.
func CreateNodeDialer ( s * options . ServerRunOptions ) ( tunneler . Tunneler , * http . Transport , error ) {
2017-01-09 18:27:59 +00:00
// Setup nodeTunneler if needed
var nodeTunneler tunneler . Tunneler
2016-12-14 09:44:11 +00:00
var proxyDialerFn utilnet . DialFunc
2015-10-09 05:18:16 +00:00
if len ( s . SSHUser ) > 0 {
// Get ssh key distribution func, if supported
2017-01-09 18:27:59 +00:00
var installSSHKey tunneler . InstallSSHKey
2017-01-04 17:57:06 +00:00
cloud , err := cloudprovider . InitCloudProvider ( s . CloudProvider . CloudProvider , s . CloudProvider . CloudConfigFile )
2016-04-27 21:25:59 +00:00
if err != nil {
2017-05-29 03:28:41 +00:00
return nil , nil , fmt . Errorf ( "cloud provider could not be initialized: %v" , err )
2016-04-27 21:25:59 +00:00
}
2015-10-09 05:18:16 +00:00
if cloud != nil {
if instances , supported := cloud . Instances ( ) ; supported {
2017-01-09 18:27:59 +00:00
installSSHKey = instances . AddSSHKeyToAllInstances
2015-10-09 05:18:16 +00:00
}
}
2015-12-05 02:01:29 +00:00
if s . KubeletConfig . Port == 0 {
2017-05-29 03:28:41 +00:00
return nil , nil , fmt . Errorf ( "must enable kubelet port if proxy ssh-tunneling is specified" )
2015-12-05 02:01:29 +00:00
}
2016-11-18 23:07:59 +00:00
if s . KubeletConfig . ReadOnlyPort == 0 {
2017-05-29 03:28:41 +00:00
return nil , nil , fmt . Errorf ( "must enable kubelet readonly port if proxy ssh-tunneling is specified" )
2016-11-18 23:07:59 +00:00
}
2017-01-09 18:27:59 +00:00
// Set up the nodeTunneler
2015-12-05 02:01:29 +00:00
// TODO(cjcullen): If we want this to handle per-kubelet ports or other
// kubelet listen-addresses, we need to plumb through options.
healthCheckPath := & url . URL {
2016-11-18 23:07:59 +00:00
Scheme : "http" ,
Host : net . JoinHostPort ( "127.0.0.1" , strconv . FormatUint ( uint64 ( s . KubeletConfig . ReadOnlyPort ) , 10 ) ) ,
2015-12-05 02:01:29 +00:00
Path : "healthz" ,
}
2017-01-09 18:27:59 +00:00
nodeTunneler = tunneler . New ( s . SSHUser , s . SSHKeyfile , healthCheckPath , installSSHKey )
2015-10-09 05:18:16 +00:00
2017-01-09 18:27:59 +00:00
// Use the nodeTunneler's dialer when proxying to pods, services, and nodes
proxyDialerFn = nodeTunneler . Dial
2015-10-09 05:18:16 +00:00
}
// Proxying to pods and services is IP-based... don't expect to be able to verify the hostname
proxyTLSClientConfig := & tls . Config { InsecureSkipVerify : true }
2017-03-15 15:26:37 +00:00
proxyTransport := utilnet . SetTransportDefaults ( & http . Transport {
Dial : proxyDialerFn ,
TLSClientConfig : proxyTLSClientConfig ,
} )
2017-05-29 03:28:41 +00:00
return nodeTunneler , proxyTransport , nil
}
// CreateKubeAPIServerConfig creates all the resources for running the API server, but runs none of them
2017-08-10 18:25:41 +00:00
func CreateKubeAPIServerConfig ( s * options . ServerRunOptions , nodeTunneler tunneler . Tunneler , proxyTransport * http . Transport ) ( * master . Config , informers . SharedInformerFactory , clientgoinformers . SharedInformerFactory , * kubeserver . InsecureServingInfo , aggregatorapiserver . ServiceResolver , error ) {
2017-05-29 03:28:41 +00:00
// set defaults in the options before trying to create the generic config
if err := defaultOptions ( s ) ; err != nil {
2017-06-21 17:02:52 +00:00
return nil , nil , nil , nil , nil , err
2017-05-29 03:28:41 +00:00
}
// validate options
if errs := s . Validate ( ) ; len ( errs ) != 0 {
2017-06-21 17:02:52 +00:00
return nil , nil , nil , nil , nil , utilerrors . NewAggregate ( errs )
2017-05-29 03:28:41 +00:00
}
2017-08-10 18:25:41 +00:00
genericConfig , sharedInformers , versionedInformers , insecureServingOptions , serviceResolver , err := BuildGenericConfig ( s , proxyTransport )
2017-05-29 03:28:41 +00:00
if err != nil {
2017-06-21 17:02:52 +00:00
return nil , nil , nil , nil , nil , err
2017-05-29 03:28:41 +00:00
}
2017-06-02 15:31:47 +00:00
if _ , port , err := net . SplitHostPort ( s . Etcd . StorageConfig . ServerList [ 0 ] ) ; err == nil && port != "0" && len ( port ) != 0 {
if err := utilwait . PollImmediate ( etcdRetryInterval , etcdRetryLimit * etcdRetryInterval , preflight . EtcdConnection { ServerList : s . Etcd . StorageConfig . ServerList } . CheckEtcdServers ) ; err != nil {
return nil , nil , nil , nil , nil , fmt . Errorf ( "error waiting for etcd connection: %v" , err )
}
2017-05-29 03:28:41 +00:00
}
capabilities . Initialize ( capabilities . Capabilities {
AllowPrivileged : s . AllowPrivileged ,
// TODO(vmarmol): Implement support for HostNetworkSources.
PrivilegedSources : capabilities . PrivilegedSources {
HostNetworkSources : [ ] string { } ,
HostPIDSources : [ ] string { } ,
HostIPCSources : [ ] string { } ,
} ,
PerConnectionBandwidthLimitBytesPerSec : s . MaxConnectionBytesPerSec ,
} )
2015-10-09 05:18:16 +00:00
2017-03-15 15:26:37 +00:00
serviceIPRange , apiServerServiceIP , err := master . DefaultServiceIPRange ( s . ServiceClusterIPRange )
if err != nil {
2017-06-21 17:02:52 +00:00
return nil , nil , nil , nil , nil , err
2017-03-15 15:26:37 +00:00
}
2016-10-04 07:17:44 +00:00
2017-03-15 15:26:37 +00:00
storageFactory , err := BuildStorageFactory ( s )
if err != nil {
2017-06-21 17:02:52 +00:00
return nil , nil , nil , nil , nil , err
2016-10-04 07:17:44 +00:00
}
2017-03-15 15:26:37 +00:00
clientCA , err := readCAorNil ( s . Authentication . ClientCert . ClientCA )
2015-10-13 00:40:37 +00:00
if err != nil {
2017-06-21 17:02:52 +00:00
return nil , nil , nil , nil , nil , err
2015-05-11 23:09:25 +00:00
}
2017-03-15 15:26:37 +00:00
requestHeaderProxyCA , err := readCAorNil ( s . Authentication . RequestHeader . ClientCAFile )
2015-01-30 17:04:39 +00:00
if err != nil {
2017-06-21 17:02:52 +00:00
return nil , nil , nil , nil , nil , err
2015-01-30 17:04:39 +00:00
}
2016-02-17 17:11:31 +00:00
2017-03-15 15:26:37 +00:00
config := & master . Config {
GenericConfig : genericConfig ,
2017-09-06 15:46:05 +00:00
ExtraConfig : master . ExtraConfig {
ClientCARegistrationHook : master . ClientCARegistrationHook {
ClientCA : clientCA ,
RequestHeaderUsernameHeaders : s . Authentication . RequestHeader . UsernameHeaders ,
RequestHeaderGroupHeaders : s . Authentication . RequestHeader . GroupHeaders ,
RequestHeaderExtraHeaderPrefixes : s . Authentication . RequestHeader . ExtraHeaderPrefixes ,
RequestHeaderCA : requestHeaderProxyCA ,
RequestHeaderAllowedNames : s . Authentication . RequestHeader . AllowedNames ,
} ,
APIResourceConfigSource : storageFactory . APIResourceConfigSource ,
StorageFactory : storageFactory ,
EnableCoreControllers : true ,
EventTTL : s . EventTTL ,
KubeletClientConfig : s . KubeletConfig ,
EnableUISupport : true ,
EnableLogsSupport : s . EnableLogsHandler ,
ProxyTransport : proxyTransport ,
Tunneler : nodeTunneler ,
ServiceIPRange : serviceIPRange ,
APIServerServiceIP : apiServerServiceIP ,
APIServerServicePort : 443 ,
ServiceNodePortRange : s . ServiceNodePortRange ,
KubernetesServiceNodePort : s . KubernetesServiceNodePort ,
2017-09-11 15:13:47 +00:00
EndpointReconcilerType : reconcilers . Type ( s . EndpointReconcilerType ) ,
MasterCount : s . MasterCount ,
2017-03-15 15:26:37 +00:00
} ,
2016-04-15 22:30:15 +00:00
}
2017-06-08 16:19:12 +00:00
if nodeTunneler != nil {
// Use the nodeTunneler's dialer to connect to the kubelet
2017-09-06 15:46:05 +00:00
config . ExtraConfig . KubeletClientConfig . Dial = nodeTunneler . Dial
2017-06-08 16:19:12 +00:00
}
2017-06-21 17:02:52 +00:00
return config , sharedInformers , versionedInformers , insecureServingOptions , serviceResolver , nil
2017-03-15 15:26:37 +00:00
}
// BuildGenericConfig takes the master server options and produces the genericapiserver.Config associated with it
2017-08-10 18:25:41 +00:00
func BuildGenericConfig ( s * options . ServerRunOptions , proxyTransport * http . Transport ) ( * genericapiserver . Config , informers . SharedInformerFactory , clientgoinformers . SharedInformerFactory , * kubeserver . InsecureServingInfo , aggregatorapiserver . ServiceResolver , error ) {
2017-10-16 11:41:50 +00:00
genericConfig := genericapiserver . NewConfig ( legacyscheme . Codecs )
2017-03-15 15:26:37 +00:00
if err := s . GenericServerRunOptions . ApplyTo ( genericConfig ) ; err != nil {
2017-06-21 17:02:52 +00:00
return nil , nil , nil , nil , nil , err
2017-03-15 15:26:37 +00:00
}
2017-03-09 19:39:56 +00:00
insecureServingOptions , err := s . InsecureServing . ApplyTo ( genericConfig )
if err != nil {
2017-06-21 17:02:52 +00:00
return nil , nil , nil , nil , nil , err
2017-03-15 15:26:37 +00:00
}
if err := s . SecureServing . ApplyTo ( genericConfig ) ; err != nil {
2017-06-21 17:02:52 +00:00
return nil , nil , nil , nil , nil , err
2017-03-15 15:26:37 +00:00
}
if err := s . Authentication . ApplyTo ( genericConfig ) ; err != nil {
2017-06-21 17:02:52 +00:00
return nil , nil , nil , nil , nil , err
2017-03-15 15:26:37 +00:00
}
if err := s . Audit . ApplyTo ( genericConfig ) ; err != nil {
2017-06-21 17:02:52 +00:00
return nil , nil , nil , nil , nil , err
2017-03-15 15:26:37 +00:00
}
if err := s . Features . ApplyTo ( genericConfig ) ; err != nil {
2017-06-21 17:02:52 +00:00
return nil , nil , nil , nil , nil , err
2015-05-01 16:02:38 +00:00
}
2015-12-24 21:54:40 +00:00
2017-10-16 11:41:50 +00:00
genericConfig . OpenAPIConfig = genericapiserver . DefaultOpenAPIConfig ( generatedopenapi . GetOpenAPIDefinitions , legacyscheme . Scheme )
2017-03-15 15:26:37 +00:00
genericConfig . OpenAPIConfig . PostProcessSpec = postProcessOpenAPISpecForBackwardCompatibility
genericConfig . OpenAPIConfig . Info . Title = "Kubernetes"
genericConfig . SwaggerConfig = genericapiserver . DefaultSwaggerConfig ( )
genericConfig . EnableMetrics = true
genericConfig . LongRunningFunc = filters . BasicLongRunningRequestCheck (
sets . NewString ( "watch" , "proxy" ) ,
sets . NewString ( "attach" , "exec" , "proxy" , "log" , "portforward" ) ,
)
kubeVersion := version . Get ( )
genericConfig . Version = & kubeVersion
storageFactory , err := BuildStorageFactory ( s )
if err != nil {
2017-06-21 17:02:52 +00:00
return nil , nil , nil , nil , nil , err
2017-03-15 15:26:37 +00:00
}
if err := s . Etcd . ApplyWithStorageFactoryTo ( storageFactory , genericConfig ) ; err != nil {
2017-06-21 17:02:52 +00:00
return nil , nil , nil , nil , nil , err
2015-12-24 21:54:40 +00:00
}
2017-03-15 15:26:37 +00:00
// Use protobufs for self-communication.
// Since not every generic apiserver has to support protobufs, we
// cannot default to it in generic apiserver and need to explicitly
// set it in kube-apiserver.
genericConfig . LoopbackClientConfig . ContentConfig . ContentType = "application/vnd.kubernetes.protobuf"
2017-02-07 16:02:47 +00:00
client , err := internalclientset . NewForConfig ( genericConfig . LoopbackClientConfig )
2016-10-04 20:02:56 +00:00
if err != nil {
2016-12-13 08:22:48 +00:00
kubeAPIVersions := os . Getenv ( "KUBE_API_VERSIONS" )
if len ( kubeAPIVersions ) == 0 {
2017-06-21 17:02:52 +00:00
return nil , nil , nil , nil , nil , fmt . Errorf ( "failed to create clientset: %v" , err )
2016-12-13 08:22:48 +00:00
}
// KUBE_API_VERSIONS is used in test-update-storage-objects.sh, disabling a number of API
// groups. This leads to a nil client above and undefined behaviour further down.
2017-02-16 22:40:55 +00:00
//
2016-12-13 08:22:48 +00:00
// TODO: get rid of KUBE_API_VERSIONS or define sane behaviour if set
glog . Errorf ( "Failed to create clientset with KUBE_API_VERSIONS=%q. KUBE_API_VERSIONS is only for testing. Things will break." , kubeAPIVersions )
2016-10-04 20:02:56 +00:00
}
2017-02-16 22:40:55 +00:00
2017-10-03 16:08:30 +00:00
kubeClientConfig := genericConfig . LoopbackClientConfig
sharedInformers := informers . NewSharedInformerFactory ( client , 10 * time . Minute )
clientgoExternalClient , err := clientgoclientset . NewForConfig ( kubeClientConfig )
2017-06-02 00:11:23 +00:00
if err != nil {
2017-06-21 17:02:52 +00:00
return nil , nil , nil , nil , nil , fmt . Errorf ( "failed to create real external clientset: %v" , err )
2017-06-02 00:11:23 +00:00
}
2017-06-21 17:02:52 +00:00
versionedInformers := clientgoinformers . NewSharedInformerFactory ( clientgoExternalClient , 10 * time . Minute )
2017-06-02 00:11:23 +00:00
var serviceResolver aggregatorapiserver . ServiceResolver
if s . EnableAggregatorRouting {
serviceResolver = aggregatorapiserver . NewEndpointServiceResolver (
2017-06-21 17:02:52 +00:00
versionedInformers . Core ( ) . V1 ( ) . Services ( ) . Lister ( ) ,
versionedInformers . Core ( ) . V1 ( ) . Endpoints ( ) . Lister ( ) ,
2017-06-02 00:11:23 +00:00
)
} else {
serviceResolver = aggregatorapiserver . NewClusterIPServiceResolver (
2017-06-21 17:02:52 +00:00
versionedInformers . Core ( ) . V1 ( ) . Services ( ) . Lister ( ) ,
2017-06-02 00:11:23 +00:00
)
}
2017-03-15 15:26:37 +00:00
genericConfig . Authenticator , genericConfig . OpenAPIConfig . SecurityDefinitions , err = BuildAuthenticator ( s , storageFactory , client , sharedInformers )
if err != nil {
2017-06-21 17:02:52 +00:00
return nil , nil , nil , nil , nil , fmt . Errorf ( "invalid authentication config: %v" , err )
2017-02-16 22:40:55 +00:00
}
2017-07-14 03:24:27 +00:00
genericConfig . Authorizer , genericConfig . RuleResolver , err = BuildAuthorizer ( s , sharedInformers )
2017-02-16 22:40:55 +00:00
if err != nil {
2017-06-21 17:02:52 +00:00
return nil , nil , nil , nil , nil , fmt . Errorf ( "invalid authorization config: %v" , err )
2017-02-16 22:40:55 +00:00
}
2017-03-31 01:40:51 +00:00
if ! sets . NewString ( s . Authorization . Modes ( ) ... ) . Has ( modes . ModeRBAC ) {
genericConfig . DisabledPostStartHooks . Insert ( rbacrest . PostStartHookName )
}
2016-05-25 21:20:41 +00:00
2017-10-24 12:48:05 +00:00
webhookAuthResolver := func ( delegate webhook . AuthenticationInfoResolver ) webhook . AuthenticationInfoResolver {
return webhook . AuthenticationInfoResolverFunc ( func ( server string ) ( * rest . Config , error ) {
if server == "kubernetes.default.svc" {
return genericConfig . LoopbackClientConfig , nil
}
ret , err := delegate . ClientConfigFor ( server )
if err != nil {
return nil , err
}
if proxyTransport != nil && proxyTransport . Dial != nil {
ret . Dial = proxyTransport . Dial
}
return ret , err
} )
}
2017-05-01 13:07:46 +00:00
pluginInitializer , err := BuildAdmissionPluginInitializer (
s ,
2017-03-27 11:26:03 +00:00
client ,
sharedInformers ,
2017-06-02 00:11:23 +00:00
serviceResolver ,
2017-10-24 12:48:05 +00:00
webhookAuthResolver ,
2017-03-27 11:26:03 +00:00
)
2015-01-30 17:04:39 +00:00
if err != nil {
2017-06-21 17:02:52 +00:00
return nil , nil , nil , nil , nil , fmt . Errorf ( "failed to create admission plugin initializer: %v" , err )
2015-01-30 17:04:39 +00:00
}
2017-05-01 13:07:46 +00:00
err = s . Admission . ApplyTo (
genericConfig ,
2017-09-06 16:22:23 +00:00
versionedInformers ,
2017-10-03 16:08:30 +00:00
kubeClientConfig ,
2017-10-16 11:41:50 +00:00
legacyscheme . Scheme ,
2017-05-01 13:07:46 +00:00
pluginInitializer )
if err != nil {
2017-06-21 17:02:52 +00:00
return nil , nil , nil , nil , nil , fmt . Errorf ( "failed to initialize admission: %v" , err )
2017-05-01 13:07:46 +00:00
}
2017-11-02 11:29:31 +00:00
2017-06-21 17:02:52 +00:00
return genericConfig , sharedInformers , versionedInformers , insecureServingOptions , serviceResolver , nil
2017-03-15 15:26:37 +00:00
}
2017-05-01 13:07:46 +00:00
// BuildAdmissionPluginInitializer constructs the admission plugin initializer
2017-10-24 12:48:05 +00:00
func BuildAdmissionPluginInitializer ( s * options . ServerRunOptions , client internalclientset . Interface , sharedInformers informers . SharedInformerFactory , serviceResolver aggregatorapiserver . ServiceResolver , webhookAuthWrapper webhook . AuthenticationInfoResolverWrapper ) ( admission . PluginInitializer , error ) {
2017-01-26 16:04:23 +00:00
var cloudConfig [ ] byte
if s . CloudProvider . CloudConfigFile != "" {
2017-05-01 13:07:46 +00:00
var err error
2017-01-26 16:04:23 +00:00
cloudConfig , err = ioutil . ReadFile ( s . CloudProvider . CloudConfigFile )
if err != nil {
glog . Fatalf ( "Error reading from cloud configuration file %s: %#v" , s . CloudProvider . CloudConfigFile , err )
}
}
2017-05-01 13:07:46 +00:00
2017-03-25 01:13:57 +00:00
// TODO: use a dynamic restmapper. See https://github.com/kubernetes/kubernetes/pull/42615.
2017-10-16 11:41:50 +00:00
restMapper := legacyscheme . Registry . RESTMapper ( )
2017-05-18 18:00:02 +00:00
2017-10-27 15:08:14 +00:00
quotaConfiguration := quotainstall . NewQuotaConfigurationForAdmission ( )
2017-05-18 18:00:02 +00:00
2017-10-27 15:08:14 +00:00
pluginInitializer := kubeapiserveradmission . NewPluginInitializer ( client , sharedInformers , cloudConfig , restMapper , quotaConfiguration , webhookAuthWrapper , serviceResolver )
2017-06-02 00:11:23 +00:00
2017-05-01 13:07:46 +00:00
return pluginInitializer , nil
2017-03-15 15:26:37 +00:00
}
2017-02-11 11:14:34 +00:00
2017-03-15 15:26:37 +00:00
// BuildAuthenticator constructs the authenticator
func BuildAuthenticator ( s * options . ServerRunOptions , storageFactory serverstorage . StorageFactory , client internalclientset . Interface , sharedInformers informers . SharedInformerFactory ) ( authenticator . Request , * spec . SecurityDefinitions , error ) {
authenticatorConfig := s . Authentication . ToAuthenticationConfig ( )
if s . Authentication . ServiceAccounts . Lookup {
// we have to go direct to storage because the clientsets fail when they're initialized with some API versions excluded
// we should stop trying to control them like that.
2017-06-21 03:49:10 +00:00
storageConfigServiceAccounts , err := storageFactory . NewConfig ( api . Resource ( "serviceaccounts" ) )
2017-03-15 15:26:37 +00:00
if err != nil {
return nil , nil , fmt . Errorf ( "unable to get serviceaccounts storage: %v" , err )
}
2017-06-21 03:49:10 +00:00
storageConfigSecrets , err := storageFactory . NewConfig ( api . Resource ( "secrets" ) )
if err != nil {
return nil , nil , fmt . Errorf ( "unable to get secrets storage: %v" , err )
}
authenticatorConfig . ServiceAccountTokenGetter = serviceaccountcontroller . NewGetterFromStorageInterface (
storageConfigServiceAccounts ,
storageFactory . ResourcePrefix ( api . Resource ( "serviceaccounts" ) ) ,
storageConfigSecrets ,
storageFactory . ResourcePrefix ( api . Resource ( "secrets" ) ) ,
)
2017-02-07 19:52:50 +00:00
}
2017-03-15 15:26:37 +00:00
if client == nil || reflect . ValueOf ( client ) . IsNil ( ) {
// TODO: Remove check once client can never be nil.
glog . Errorf ( "Failed to setup bootstrap token authenticator because the loopback clientset was not setup properly." )
} else {
authenticatorConfig . BootstrapTokenAuthenticator = bootstrap . NewTokenAuthenticator (
sharedInformers . Core ( ) . InternalVersion ( ) . Secrets ( ) . Lister ( ) . Secrets ( v1 . NamespaceSystem ) ,
)
}
return authenticatorConfig . New ( )
}
2016-04-15 01:01:31 +00:00
2017-03-15 15:26:37 +00:00
// BuildAuthorizer constructs the authorizer
2017-07-14 03:24:27 +00:00
func BuildAuthorizer ( s * options . ServerRunOptions , sharedInformers informers . SharedInformerFactory ) ( authorizer . Authorizer , authorizer . RuleResolver , error ) {
2017-03-15 15:26:37 +00:00
authorizationConfig := s . Authorization . ToAuthorizationConfig ( sharedInformers )
return authorizationConfig . New ( )
}
2017-08-28 09:54:04 +00:00
// BuildStorageFactory constructs the storage factory. If encryption at rest is used, it expects
// all supported KMS plugins to be registered in the KMS plugin registry before being called.
2017-03-15 15:26:37 +00:00
func BuildStorageFactory ( s * options . ServerRunOptions ) ( * serverstorage . DefaultStorageFactory , error ) {
storageGroupsToEncodingVersion , err := s . StorageSerialization . StorageGroupsToEncodingVersion ( )
2017-02-21 12:48:04 +00:00
if err != nil {
2017-03-15 15:26:37 +00:00
return nil , fmt . Errorf ( "error generating storage version map: %s" , err )
2017-02-21 12:48:04 +00:00
}
2017-03-15 15:26:37 +00:00
storageFactory , err := kubeapiserver . NewStorageFactory (
2017-10-16 11:41:50 +00:00
s . Etcd . StorageConfig , s . Etcd . DefaultStorageMediaType , legacyscheme . Codecs ,
serverstorage . NewDefaultResourceEncodingConfig ( legacyscheme . Registry ) , storageGroupsToEncodingVersion ,
2017-08-28 12:17:21 +00:00
// FIXME (soltysh): this GroupVersionResource override should be configurable
[ ] schema . GroupVersionResource { batch . Resource ( "cronjobs" ) . WithVersion ( "v1beta1" ) } ,
2017-03-15 15:26:37 +00:00
master . DefaultAPIResourceConfigSource ( ) , s . APIEnablement . RuntimeConfig )
2017-02-21 12:48:04 +00:00
if err != nil {
2017-03-15 15:26:37 +00:00
return nil , fmt . Errorf ( "error in initializing storage factory: %s" , err )
2017-02-21 12:48:04 +00:00
}
2016-09-19 18:52:41 +00:00
2017-07-19 17:44:42 +00:00
// keep Deployments, NetworkPolicies, Daemonsets and ReplicaSets in extensions for backwards compatibility, we'll have to migrate at some point, eventually
2017-03-15 15:26:37 +00:00
storageFactory . AddCohabitatingResources ( extensions . Resource ( "deployments" ) , apps . Resource ( "deployments" ) )
2017-07-17 22:56:48 +00:00
storageFactory . AddCohabitatingResources ( extensions . Resource ( "daemonsets" ) , apps . Resource ( "daemonsets" ) )
2017-07-19 17:44:42 +00:00
storageFactory . AddCohabitatingResources ( extensions . Resource ( "replicasets" ) , apps . Resource ( "replicasets" ) )
2017-03-13 14:31:16 +00:00
storageFactory . AddCohabitatingResources ( extensions . Resource ( "networkpolicies" ) , networking . Resource ( "networkpolicies" ) )
2017-03-15 15:26:37 +00:00
for _ , override := range s . Etcd . EtcdServersOverrides {
tokens := strings . Split ( override , "#" )
if len ( tokens ) != 2 {
glog . Errorf ( "invalid value of etcd server overrides: %s" , override )
continue
}
2017-02-21 12:48:04 +00:00
2017-03-15 15:26:37 +00:00
apiresource := strings . Split ( tokens [ 0 ] , "/" )
if len ( apiresource ) != 2 {
glog . Errorf ( "invalid resource definition: %s" , tokens [ 0 ] )
continue
}
group := apiresource [ 0 ]
resource := apiresource [ 1 ]
groupResource := schema . GroupResource { Group : group , Resource : resource }
2015-11-16 21:46:00 +00:00
2017-03-15 15:26:37 +00:00
servers := strings . Split ( tokens [ 1 ] , ";" )
storageFactory . SetEtcdLocation ( groupResource , servers )
}
2016-10-31 19:51:52 +00:00
2017-08-28 09:54:04 +00:00
if len ( s . Etcd . EncryptionProviderConfigFilepath ) != 0 {
2017-05-24 00:30:49 +00:00
transformerOverrides , err := encryptionconfig . GetTransformerOverrides ( s . Etcd . EncryptionProviderConfigFilepath )
if err != nil {
return nil , err
}
for groupResource , transformer := range transformerOverrides {
storageFactory . SetTransformer ( groupResource , transformer )
}
}
2017-03-15 15:26:37 +00:00
return storageFactory , nil
}
2016-10-31 19:51:52 +00:00
2017-03-15 15:26:37 +00:00
func defaultOptions ( s * options . ServerRunOptions ) error {
2017-03-09 18:51:59 +00:00
// set defaults
if err := s . GenericServerRunOptions . DefaultAdvertiseAddress ( s . SecureServing ) ; err != nil {
return err
}
if err := kubeoptions . DefaultAdvertiseAddress ( s . GenericServerRunOptions , s . InsecureServing ) ; err != nil {
2017-03-15 15:26:37 +00:00
return err
}
2017-09-21 22:15:45 +00:00
serviceIPRange , apiServerServiceIP , err := master . DefaultServiceIPRange ( s . ServiceClusterIPRange )
2017-03-15 15:26:37 +00:00
if err != nil {
return fmt . Errorf ( "error determining service IP ranges: %v" , err )
}
2017-09-21 22:15:45 +00:00
s . ServiceClusterIPRange = serviceIPRange
2017-03-20 20:02:42 +00:00
if err := s . SecureServing . MaybeDefaultWithSelfSignedCerts ( s . GenericServerRunOptions . AdvertiseAddress . String ( ) , [ ] string { "kubernetes.default.svc" , "kubernetes.default" , "kubernetes" } , [ ] net . IP { apiServerServiceIP } ) ; err != nil {
2017-03-15 15:26:37 +00:00
return fmt . Errorf ( "error creating self-signed certificates: %v" , err )
}
if err := s . CloudProvider . DefaultExternalHost ( s . GenericServerRunOptions ) ; err != nil {
return fmt . Errorf ( "error setting the external host value: %v" , err )
}
2016-10-31 19:51:52 +00:00
2017-03-15 15:26:37 +00:00
s . Authentication . ApplyAuthorization ( s . Authorization )
// Default to the private server key for service account token signing
if len ( s . Authentication . ServiceAccounts . KeyFiles ) == 0 && s . SecureServing . ServerCert . CertKey . KeyFile != "" {
if kubeauthenticator . IsValidServiceAccountKeyFile ( s . SecureServing . ServerCert . CertKey . KeyFile ) {
s . Authentication . ServiceAccounts . KeyFiles = [ ] string { s . SecureServing . ServerCert . CertKey . KeyFile }
} else {
glog . Warning ( "No TLS key provided, service account token authentication disabled" )
}
2015-01-30 17:04:39 +00:00
}
2016-02-05 07:47:27 +00:00
2017-03-15 15:26:37 +00:00
if s . Etcd . StorageConfig . DeserializationCacheSize == 0 {
// When size of cache is not explicitly set, estimate its size based on
// target memory usage.
glog . V ( 2 ) . Infof ( "Initializing deserialization cache size based on %dMB limit" , s . GenericServerRunOptions . TargetRAMMB )
// This is the heuristics that from memory capacity is trying to infer
// the maximum number of nodes in the cluster and set cache sizes based
// on that value.
2017-05-24 20:41:33 +00:00
// From our documentation, we officially recommend 120GB machines for
2017-03-15 15:26:37 +00:00
// 2000 nodes, and we scale from that point. Thus we assume ~60MB of
// capacity per node.
// TODO: We may consider deciding that some percentage of memory will
// be used for the deserialization cache and divide it by the max object
// size to compute its size. We may even go further and measure
// collective sizes of the objects in the cache.
clusterSize := s . GenericServerRunOptions . TargetRAMMB / 60
s . Etcd . StorageConfig . DeserializationCacheSize = 25 * clusterSize
if s . Etcd . StorageConfig . DeserializationCacheSize < 1000 {
s . Etcd . StorageConfig . DeserializationCacheSize = 1000
}
}
2017-02-07 19:35:02 +00:00
if s . Etcd . EnableWatchCache {
2016-12-01 07:24:44 +00:00
glog . V ( 2 ) . Infof ( "Initializing cache sizes based on %dMB limit" , s . GenericServerRunOptions . TargetRAMMB )
2017-09-07 20:59:31 +00:00
sizes := cachesize . NewHeuristicWatchCacheSizes ( s . GenericServerRunOptions . TargetRAMMB )
if userSpecified , err := serveroptions . ParseWatchCacheSizes ( s . Etcd . WatchCacheSizes ) ; err == nil {
for resource , size := range userSpecified {
sizes [ resource ] = size
}
}
s . Etcd . WatchCacheSizes , err = serveroptions . WriteWatchCacheSizes ( sizes )
if err != nil {
return err
}
2016-02-05 07:47:27 +00:00
}
2017-03-15 15:26:37 +00:00
return nil
2015-01-30 17:04:39 +00:00
}
2017-02-02 00:05:55 +00:00
2017-02-21 12:48:04 +00:00
func readCAorNil ( file string ) ( [ ] byte , error ) {
if len ( file ) == 0 {
return nil , nil
}
return ioutil . ReadFile ( file )
}
2017-02-02 00:05:55 +00:00
// PostProcessSpec adds removed definitions for backward compatibility
func postProcessOpenAPISpecForBackwardCompatibility ( s * spec . Swagger ) ( * spec . Swagger , error ) {
compatibilityMap := map [ string ] string {
2017-11-07 20:46:54 +00:00
"io.k8s.kubernetes.pkg.apis.authorization.v1beta1.SelfSubjectAccessReview" : "io.k8s.api.authorization.v1beta1.SelfSubjectAccessReview" ,
"io.k8s.kubernetes.pkg.api.v1.GitRepoVolumeSource" : "io.k8s.api.core.v1.GitRepoVolumeSource" ,
"io.k8s.kubernetes.pkg.apis.admissionregistration.v1alpha1.ValidatingWebhookConfigurationList" : "io.k8s.api.admissionregistration.v1alpha1.ValidatingWebhookConfigurationList" ,
"io.k8s.kubernetes.pkg.api.v1.EndpointPort" : "io.k8s.api.core.v1.EndpointPort" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.SupplementalGroupsStrategyOptions" : "io.k8s.api.extensions.v1beta1.SupplementalGroupsStrategyOptions" ,
"io.k8s.kubernetes.pkg.api.v1.PodStatus" : "io.k8s.api.core.v1.PodStatus" ,
"io.k8s.kubernetes.pkg.apis.rbac.v1beta1.RoleBindingList" : "io.k8s.api.rbac.v1beta1.RoleBindingList" ,
"io.k8s.kubernetes.pkg.apis.policy.v1beta1.PodDisruptionBudgetSpec" : "io.k8s.api.policy.v1beta1.PodDisruptionBudgetSpec" ,
"io.k8s.kubernetes.pkg.api.v1.HTTPGetAction" : "io.k8s.api.core.v1.HTTPGetAction" ,
"io.k8s.kubernetes.pkg.apis.authorization.v1.ResourceAttributes" : "io.k8s.api.authorization.v1.ResourceAttributes" ,
"io.k8s.kubernetes.pkg.api.v1.PersistentVolumeList" : "io.k8s.api.core.v1.PersistentVolumeList" ,
"io.k8s.kubernetes.pkg.apis.batch.v2alpha1.CronJobSpec" : "io.k8s.api.batch.v2alpha1.CronJobSpec" ,
"io.k8s.kubernetes.pkg.api.v1.CephFSVolumeSource" : "io.k8s.api.core.v1.CephFSVolumeSource" ,
"io.k8s.kubernetes.pkg.api.v1.Affinity" : "io.k8s.api.core.v1.Affinity" ,
"io.k8s.kubernetes.pkg.apis.rbac.v1beta1.PolicyRule" : "io.k8s.api.rbac.v1beta1.PolicyRule" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.DaemonSetSpec" : "io.k8s.api.extensions.v1beta1.DaemonSetSpec" ,
"io.k8s.kubernetes.pkg.api.v1.ProjectedVolumeSource" : "io.k8s.api.core.v1.ProjectedVolumeSource" ,
"io.k8s.kubernetes.pkg.api.v1.TCPSocketAction" : "io.k8s.api.core.v1.TCPSocketAction" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.DaemonSet" : "io.k8s.api.extensions.v1beta1.DaemonSet" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.IngressList" : "io.k8s.api.extensions.v1beta1.IngressList" ,
"io.k8s.kubernetes.pkg.api.v1.PodSpec" : "io.k8s.api.core.v1.PodSpec" ,
"io.k8s.kubernetes.pkg.apis.authentication.v1.TokenReview" : "io.k8s.api.authentication.v1.TokenReview" ,
"io.k8s.kubernetes.pkg.apis.authorization.v1beta1.SubjectAccessReview" : "io.k8s.api.authorization.v1beta1.SubjectAccessReview" ,
"io.k8s.kubernetes.pkg.apis.rbac.v1alpha1.ClusterRoleBinding" : "io.k8s.api.rbac.v1alpha1.ClusterRoleBinding" ,
"io.k8s.kubernetes.pkg.api.v1.Node" : "io.k8s.api.core.v1.Node" ,
"io.k8s.kubernetes.pkg.apis.admissionregistration.v1alpha1.ServiceReference" : "io.k8s.api.admissionregistration.v1alpha1.ServiceReference" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.DeploymentStatus" : "io.k8s.api.extensions.v1beta1.DeploymentStatus" ,
"io.k8s.kubernetes.pkg.apis.rbac.v1beta1.RoleRef" : "io.k8s.api.rbac.v1beta1.RoleRef" ,
"io.k8s.kubernetes.pkg.apis.apps.v1beta1.Scale" : "io.k8s.api.apps.v1beta1.Scale" ,
"io.k8s.kubernetes.pkg.apis.admissionregistration.v1alpha1.InitializerConfiguration" : "io.k8s.api.admissionregistration.v1alpha1.InitializerConfiguration" ,
"io.k8s.kubernetes.pkg.api.v1.PhotonPersistentDiskVolumeSource" : "io.k8s.api.core.v1.PhotonPersistentDiskVolumeSource" ,
"io.k8s.kubernetes.pkg.api.v1.PreferredSchedulingTerm" : "io.k8s.api.core.v1.PreferredSchedulingTerm" ,
"io.k8s.kubernetes.pkg.apis.batch.v1.JobSpec" : "io.k8s.api.batch.v1.JobSpec" ,
"io.k8s.kubernetes.pkg.api.v1.EventSource" : "io.k8s.api.core.v1.EventSource" ,
"io.k8s.kubernetes.pkg.api.v1.Container" : "io.k8s.api.core.v1.Container" ,
"io.k8s.kubernetes.pkg.apis.admissionregistration.v1alpha1.AdmissionHookClientConfig" : "io.k8s.api.admissionregistration.v1alpha1.AdmissionHookClientConfig" ,
"io.k8s.kubernetes.pkg.api.v1.ResourceQuota" : "io.k8s.api.core.v1.ResourceQuota" ,
"io.k8s.kubernetes.pkg.api.v1.SecretList" : "io.k8s.api.core.v1.SecretList" ,
"io.k8s.kubernetes.pkg.api.v1.NodeSystemInfo" : "io.k8s.api.core.v1.NodeSystemInfo" ,
"io.k8s.kubernetes.pkg.apis.rbac.v1alpha1.PolicyRule" : "io.k8s.api.rbac.v1alpha1.PolicyRule" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.ReplicaSetSpec" : "io.k8s.api.extensions.v1beta1.ReplicaSetSpec" ,
"io.k8s.kubernetes.pkg.api.v1.NodeStatus" : "io.k8s.api.core.v1.NodeStatus" ,
"io.k8s.kubernetes.pkg.api.v1.ResourceQuotaList" : "io.k8s.api.core.v1.ResourceQuotaList" ,
"io.k8s.kubernetes.pkg.api.v1.HostPathVolumeSource" : "io.k8s.api.core.v1.HostPathVolumeSource" ,
"io.k8s.kubernetes.pkg.apis.certificates.v1beta1.CertificateSigningRequest" : "io.k8s.api.certificates.v1beta1.CertificateSigningRequest" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.IngressRule" : "io.k8s.api.extensions.v1beta1.IngressRule" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.NetworkPolicyPeer" : "io.k8s.api.extensions.v1beta1.NetworkPolicyPeer" ,
"io.k8s.kubernetes.pkg.apis.storage.v1.StorageClass" : "io.k8s.api.storage.v1.StorageClass" ,
"io.k8s.kubernetes.pkg.apis.networking.v1.NetworkPolicyPeer" : "io.k8s.api.networking.v1.NetworkPolicyPeer" ,
"io.k8s.kubernetes.pkg.apis.networking.v1.NetworkPolicyIngressRule" : "io.k8s.api.networking.v1.NetworkPolicyIngressRule" ,
"io.k8s.kubernetes.pkg.api.v1.StorageOSPersistentVolumeSource" : "io.k8s.api.core.v1.StorageOSPersistentVolumeSource" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.NetworkPolicyIngressRule" : "io.k8s.api.extensions.v1beta1.NetworkPolicyIngressRule" ,
"io.k8s.kubernetes.pkg.api.v1.PodAffinity" : "io.k8s.api.core.v1.PodAffinity" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.RollbackConfig" : "io.k8s.api.extensions.v1beta1.RollbackConfig" ,
"io.k8s.kubernetes.pkg.api.v1.PodList" : "io.k8s.api.core.v1.PodList" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.ScaleStatus" : "io.k8s.api.extensions.v1beta1.ScaleStatus" ,
"io.k8s.kubernetes.pkg.api.v1.ComponentCondition" : "io.k8s.api.core.v1.ComponentCondition" ,
"io.k8s.kubernetes.pkg.apis.certificates.v1beta1.CertificateSigningRequestList" : "io.k8s.api.certificates.v1beta1.CertificateSigningRequestList" ,
"io.k8s.kubernetes.pkg.apis.rbac.v1alpha1.ClusterRoleBindingList" : "io.k8s.api.rbac.v1alpha1.ClusterRoleBindingList" ,
"io.k8s.kubernetes.pkg.apis.autoscaling.v2alpha1.HorizontalPodAutoscalerCondition" : "io.k8s.api.autoscaling.v2alpha1.HorizontalPodAutoscalerCondition" ,
"io.k8s.kubernetes.pkg.api.v1.ServiceList" : "io.k8s.api.core.v1.ServiceList" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.PodSecurityPolicy" : "io.k8s.api.extensions.v1beta1.PodSecurityPolicy" ,
"io.k8s.kubernetes.pkg.apis.batch.v1.JobCondition" : "io.k8s.api.batch.v1.JobCondition" ,
"io.k8s.kubernetes.pkg.apis.apps.v1beta1.DeploymentStatus" : "io.k8s.api.apps.v1beta1.DeploymentStatus" ,
"io.k8s.kubernetes.pkg.api.v1.Volume" : "io.k8s.api.core.v1.Volume" ,
"io.k8s.kubernetes.pkg.apis.rbac.v1alpha1.RoleBindingList" : "io.k8s.api.rbac.v1alpha1.RoleBindingList" ,
"io.k8s.kubernetes.pkg.apis.admissionregistration.v1alpha1.Rule" : "io.k8s.api.admissionregistration.v1alpha1.Rule" ,
"io.k8s.kubernetes.pkg.apis.admissionregistration.v1alpha1.InitializerConfigurationList" : "io.k8s.api.admissionregistration.v1alpha1.InitializerConfigurationList" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.NetworkPolicy" : "io.k8s.api.extensions.v1beta1.NetworkPolicy" ,
"io.k8s.kubernetes.pkg.apis.rbac.v1alpha1.ClusterRoleList" : "io.k8s.api.rbac.v1alpha1.ClusterRoleList" ,
"io.k8s.kubernetes.pkg.api.v1.ObjectFieldSelector" : "io.k8s.api.core.v1.ObjectFieldSelector" ,
"io.k8s.kubernetes.pkg.api.v1.EventList" : "io.k8s.api.core.v1.EventList" ,
"io.k8s.kubernetes.pkg.apis.autoscaling.v2alpha1.MetricStatus" : "io.k8s.api.autoscaling.v2alpha1.MetricStatus" ,
"io.k8s.kubernetes.pkg.apis.networking.v1.NetworkPolicyPort" : "io.k8s.api.networking.v1.NetworkPolicyPort" ,
"io.k8s.kubernetes.pkg.apis.rbac.v1beta1.RoleList" : "io.k8s.api.rbac.v1beta1.RoleList" ,
"io.k8s.kubernetes.pkg.apis.rbac.v1alpha1.RoleList" : "io.k8s.api.rbac.v1alpha1.RoleList" ,
"io.k8s.kubernetes.pkg.apis.apps.v1beta1.DeploymentStrategy" : "io.k8s.api.apps.v1beta1.DeploymentStrategy" ,
"io.k8s.kubernetes.pkg.apis.autoscaling.v1.CrossVersionObjectReference" : "io.k8s.api.autoscaling.v1.CrossVersionObjectReference" ,
"io.k8s.kubernetes.pkg.api.v1.ConfigMapProjection" : "io.k8s.api.core.v1.ConfigMapProjection" ,
"io.k8s.kubernetes.pkg.apis.autoscaling.v2alpha1.CrossVersionObjectReference" : "io.k8s.api.autoscaling.v2alpha1.CrossVersionObjectReference" ,
"io.k8s.kubernetes.pkg.api.v1.LoadBalancerStatus" : "io.k8s.api.core.v1.LoadBalancerStatus" ,
"io.k8s.kubernetes.pkg.api.v1.ISCSIVolumeSource" : "io.k8s.api.core.v1.ISCSIVolumeSource" ,
"io.k8s.kubernetes.pkg.apis.apps.v1beta1.ControllerRevisionList" : "io.k8s.api.apps.v1beta1.ControllerRevisionList" ,
"io.k8s.kubernetes.pkg.api.v1.EndpointSubset" : "io.k8s.api.core.v1.EndpointSubset" ,
"io.k8s.kubernetes.pkg.api.v1.SELinuxOptions" : "io.k8s.api.core.v1.SELinuxOptions" ,
"io.k8s.kubernetes.pkg.api.v1.PersistentVolumeClaimVolumeSource" : "io.k8s.api.core.v1.PersistentVolumeClaimVolumeSource" ,
"io.k8s.kubernetes.pkg.apis.autoscaling.v2alpha1.MetricSpec" : "io.k8s.api.autoscaling.v2alpha1.MetricSpec" ,
"io.k8s.kubernetes.pkg.apis.apps.v1beta1.StatefulSetList" : "io.k8s.api.apps.v1beta1.StatefulSetList" ,
"io.k8s.kubernetes.pkg.apis.authorization.v1beta1.ResourceAttributes" : "io.k8s.api.authorization.v1beta1.ResourceAttributes" ,
"io.k8s.kubernetes.pkg.api.v1.Capabilities" : "io.k8s.api.core.v1.Capabilities" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.Deployment" : "io.k8s.api.extensions.v1beta1.Deployment" ,
"io.k8s.kubernetes.pkg.api.v1.Binding" : "io.k8s.api.core.v1.Binding" ,
"io.k8s.kubernetes.pkg.api.v1.ReplicationControllerList" : "io.k8s.api.core.v1.ReplicationControllerList" ,
"io.k8s.kubernetes.pkg.apis.authorization.v1.SelfSubjectAccessReview" : "io.k8s.api.authorization.v1.SelfSubjectAccessReview" ,
"io.k8s.kubernetes.pkg.apis.authentication.v1beta1.UserInfo" : "io.k8s.api.authentication.v1beta1.UserInfo" ,
"io.k8s.kubernetes.pkg.api.v1.HostAlias" : "io.k8s.api.core.v1.HostAlias" ,
"io.k8s.kubernetes.pkg.apis.apps.v1beta1.StatefulSetUpdateStrategy" : "io.k8s.api.apps.v1beta1.StatefulSetUpdateStrategy" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.IngressSpec" : "io.k8s.api.extensions.v1beta1.IngressSpec" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.DeploymentCondition" : "io.k8s.api.extensions.v1beta1.DeploymentCondition" ,
"io.k8s.kubernetes.pkg.api.v1.GCEPersistentDiskVolumeSource" : "io.k8s.api.core.v1.GCEPersistentDiskVolumeSource" ,
"io.k8s.kubernetes.pkg.apis.admissionregistration.v1alpha1.Webhook" : "io.k8s.api.admissionregistration.v1alpha1.Webhook" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.Scale" : "io.k8s.api.extensions.v1beta1.Scale" ,
"io.k8s.kubernetes.pkg.apis.autoscaling.v2alpha1.HorizontalPodAutoscalerStatus" : "io.k8s.api.autoscaling.v2alpha1.HorizontalPodAutoscalerStatus" ,
"io.k8s.kubernetes.pkg.api.v1.FlexVolumeSource" : "io.k8s.api.core.v1.FlexVolumeSource" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.RollingUpdateDeployment" : "io.k8s.api.extensions.v1beta1.RollingUpdateDeployment" ,
"io.k8s.kubernetes.pkg.apis.autoscaling.v2alpha1.ObjectMetricStatus" : "io.k8s.api.autoscaling.v2alpha1.ObjectMetricStatus" ,
"io.k8s.kubernetes.pkg.api.v1.Event" : "io.k8s.api.core.v1.Event" ,
"io.k8s.kubernetes.pkg.api.v1.ResourceQuotaSpec" : "io.k8s.api.core.v1.ResourceQuotaSpec" ,
"io.k8s.kubernetes.pkg.api.v1.Handler" : "io.k8s.api.core.v1.Handler" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.IngressBackend" : "io.k8s.api.extensions.v1beta1.IngressBackend" ,
"io.k8s.kubernetes.pkg.apis.rbac.v1alpha1.Role" : "io.k8s.api.rbac.v1alpha1.Role" ,
"io.k8s.kubernetes.pkg.apis.autoscaling.v2alpha1.ObjectMetricSource" : "io.k8s.api.autoscaling.v2alpha1.ObjectMetricSource" ,
"io.k8s.kubernetes.pkg.apis.autoscaling.v2alpha1.ResourceMetricStatus" : "io.k8s.api.autoscaling.v2alpha1.ResourceMetricStatus" ,
"io.k8s.kubernetes.pkg.apis.autoscaling.v1.HorizontalPodAutoscalerSpec" : "io.k8s.api.autoscaling.v1.HorizontalPodAutoscalerSpec" ,
"io.k8s.kubernetes.pkg.api.v1.Lifecycle" : "io.k8s.api.core.v1.Lifecycle" ,
"io.k8s.kubernetes.pkg.apis.certificates.v1beta1.CertificateSigningRequestStatus" : "io.k8s.api.certificates.v1beta1.CertificateSigningRequestStatus" ,
"io.k8s.kubernetes.pkg.api.v1.ContainerStateRunning" : "io.k8s.api.core.v1.ContainerStateRunning" ,
"io.k8s.kubernetes.pkg.api.v1.ServiceAccountList" : "io.k8s.api.core.v1.ServiceAccountList" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.HostPortRange" : "io.k8s.api.extensions.v1beta1.HostPortRange" ,
"io.k8s.kubernetes.pkg.apis.apps.v1beta1.ControllerRevision" : "io.k8s.api.apps.v1beta1.ControllerRevision" ,
"io.k8s.kubernetes.pkg.api.v1.ReplicationControllerSpec" : "io.k8s.api.core.v1.ReplicationControllerSpec" ,
"io.k8s.kubernetes.pkg.api.v1.ContainerStateTerminated" : "io.k8s.api.core.v1.ContainerStateTerminated" ,
"io.k8s.kubernetes.pkg.api.v1.ReplicationControllerStatus" : "io.k8s.api.core.v1.ReplicationControllerStatus" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.DaemonSetList" : "io.k8s.api.extensions.v1beta1.DaemonSetList" ,
"io.k8s.kubernetes.pkg.apis.authorization.v1.SelfSubjectAccessReviewSpec" : "io.k8s.api.authorization.v1.SelfSubjectAccessReviewSpec" ,
"io.k8s.kubernetes.pkg.api.v1.ComponentStatusList" : "io.k8s.api.core.v1.ComponentStatusList" ,
"io.k8s.kubernetes.pkg.api.v1.ContainerStateWaiting" : "io.k8s.api.core.v1.ContainerStateWaiting" ,
"io.k8s.kubernetes.pkg.api.v1.VolumeMount" : "io.k8s.api.core.v1.VolumeMount" ,
"io.k8s.kubernetes.pkg.api.v1.Secret" : "io.k8s.api.core.v1.Secret" ,
"io.k8s.kubernetes.pkg.apis.rbac.v1beta1.ClusterRoleList" : "io.k8s.api.rbac.v1beta1.ClusterRoleList" ,
"io.k8s.kubernetes.pkg.api.v1.ConfigMapList" : "io.k8s.api.core.v1.ConfigMapList" ,
"io.k8s.kubernetes.pkg.apis.storage.v1beta1.StorageClassList" : "io.k8s.api.storage.v1beta1.StorageClassList" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.HTTPIngressPath" : "io.k8s.api.extensions.v1beta1.HTTPIngressPath" ,
"io.k8s.kubernetes.pkg.apis.rbac.v1alpha1.ClusterRole" : "io.k8s.api.rbac.v1alpha1.ClusterRole" ,
"io.k8s.kubernetes.pkg.apis.autoscaling.v2alpha1.ResourceMetricSource" : "io.k8s.api.autoscaling.v2alpha1.ResourceMetricSource" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.DeploymentRollback" : "io.k8s.api.extensions.v1beta1.DeploymentRollback" ,
"io.k8s.kubernetes.pkg.api.v1.PersistentVolumeClaimSpec" : "io.k8s.api.core.v1.PersistentVolumeClaimSpec" ,
"io.k8s.kubernetes.pkg.api.v1.ReplicationController" : "io.k8s.api.core.v1.ReplicationController" ,
"io.k8s.kubernetes.pkg.apis.apps.v1beta1.StatefulSetSpec" : "io.k8s.api.apps.v1beta1.StatefulSetSpec" ,
"io.k8s.kubernetes.pkg.api.v1.SecurityContext" : "io.k8s.api.core.v1.SecurityContext" ,
"io.k8s.kubernetes.pkg.apis.networking.v1.NetworkPolicySpec" : "io.k8s.api.networking.v1.NetworkPolicySpec" ,
"io.k8s.kubernetes.pkg.api.v1.LocalObjectReference" : "io.k8s.api.core.v1.LocalObjectReference" ,
"io.k8s.kubernetes.pkg.api.v1.RBDVolumeSource" : "io.k8s.api.core.v1.RBDVolumeSource" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.NetworkPolicySpec" : "io.k8s.api.extensions.v1beta1.NetworkPolicySpec" ,
"io.k8s.kubernetes.pkg.api.v1.KeyToPath" : "io.k8s.api.core.v1.KeyToPath" ,
"io.k8s.kubernetes.pkg.api.v1.WeightedPodAffinityTerm" : "io.k8s.api.core.v1.WeightedPodAffinityTerm" ,
"io.k8s.kubernetes.pkg.apis.autoscaling.v2alpha1.PodsMetricStatus" : "io.k8s.api.autoscaling.v2alpha1.PodsMetricStatus" ,
"io.k8s.kubernetes.pkg.api.v1.NodeAddress" : "io.k8s.api.core.v1.NodeAddress" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.Ingress" : "io.k8s.api.extensions.v1beta1.Ingress" ,
"io.k8s.kubernetes.pkg.apis.policy.v1beta1.PodDisruptionBudget" : "io.k8s.api.policy.v1beta1.PodDisruptionBudget" ,
"io.k8s.kubernetes.pkg.api.v1.ServicePort" : "io.k8s.api.core.v1.ServicePort" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.IDRange" : "io.k8s.api.extensions.v1beta1.IDRange" ,
"io.k8s.kubernetes.pkg.api.v1.SecretEnvSource" : "io.k8s.api.core.v1.SecretEnvSource" ,
"io.k8s.kubernetes.pkg.api.v1.NodeSelector" : "io.k8s.api.core.v1.NodeSelector" ,
"io.k8s.kubernetes.pkg.api.v1.PersistentVolumeClaimStatus" : "io.k8s.api.core.v1.PersistentVolumeClaimStatus" ,
"io.k8s.kubernetes.pkg.apis.apps.v1beta1.DeploymentSpec" : "io.k8s.api.apps.v1beta1.DeploymentSpec" ,
"io.k8s.kubernetes.pkg.apis.authorization.v1.NonResourceAttributes" : "io.k8s.api.authorization.v1.NonResourceAttributes" ,
"io.k8s.kubernetes.pkg.apis.autoscaling.v1.ScaleStatus" : "io.k8s.api.autoscaling.v1.ScaleStatus" ,
"io.k8s.kubernetes.pkg.api.v1.PodCondition" : "io.k8s.api.core.v1.PodCondition" ,
"io.k8s.kubernetes.pkg.api.v1.PodTemplateSpec" : "io.k8s.api.core.v1.PodTemplateSpec" ,
"io.k8s.kubernetes.pkg.apis.apps.v1beta1.StatefulSet" : "io.k8s.api.apps.v1beta1.StatefulSet" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.NetworkPolicyPort" : "io.k8s.api.extensions.v1beta1.NetworkPolicyPort" ,
"io.k8s.kubernetes.pkg.apis.authentication.v1beta1.TokenReview" : "io.k8s.api.authentication.v1beta1.TokenReview" ,
"io.k8s.kubernetes.pkg.api.v1.LimitRangeSpec" : "io.k8s.api.core.v1.LimitRangeSpec" ,
"io.k8s.kubernetes.pkg.api.v1.FlockerVolumeSource" : "io.k8s.api.core.v1.FlockerVolumeSource" ,
"io.k8s.kubernetes.pkg.apis.policy.v1beta1.Eviction" : "io.k8s.api.policy.v1beta1.Eviction" ,
"io.k8s.kubernetes.pkg.api.v1.PersistentVolumeClaimList" : "io.k8s.api.core.v1.PersistentVolumeClaimList" ,
"io.k8s.kubernetes.pkg.apis.certificates.v1beta1.CertificateSigningRequestCondition" : "io.k8s.api.certificates.v1beta1.CertificateSigningRequestCondition" ,
"io.k8s.kubernetes.pkg.api.v1.DownwardAPIVolumeFile" : "io.k8s.api.core.v1.DownwardAPIVolumeFile" ,
"io.k8s.kubernetes.pkg.apis.authorization.v1beta1.LocalSubjectAccessReview" : "io.k8s.api.authorization.v1beta1.LocalSubjectAccessReview" ,
"io.k8s.kubernetes.pkg.apis.apps.v1beta1.ScaleStatus" : "io.k8s.api.apps.v1beta1.ScaleStatus" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.HTTPIngressRuleValue" : "io.k8s.api.extensions.v1beta1.HTTPIngressRuleValue" ,
"io.k8s.kubernetes.pkg.apis.batch.v1.Job" : "io.k8s.api.batch.v1.Job" ,
"io.k8s.kubernetes.pkg.apis.admissionregistration.v1alpha1.ValidatingWebhookConfiguration" : "io.k8s.api.admissionregistration.v1alpha1.ValidatingWebhookConfiguration" ,
"io.k8s.kubernetes.pkg.apis.rbac.v1beta1.RoleBinding" : "io.k8s.api.rbac.v1beta1.RoleBinding" ,
"io.k8s.kubernetes.pkg.api.v1.FCVolumeSource" : "io.k8s.api.core.v1.FCVolumeSource" ,
"io.k8s.kubernetes.pkg.api.v1.EndpointAddress" : "io.k8s.api.core.v1.EndpointAddress" ,
"io.k8s.kubernetes.pkg.api.v1.ContainerPort" : "io.k8s.api.core.v1.ContainerPort" ,
"io.k8s.kubernetes.pkg.apis.rbac.v1beta1.ClusterRoleBinding" : "io.k8s.api.rbac.v1beta1.ClusterRoleBinding" ,
"io.k8s.kubernetes.pkg.api.v1.GlusterfsVolumeSource" : "io.k8s.api.core.v1.GlusterfsVolumeSource" ,
"io.k8s.kubernetes.pkg.api.v1.ResourceRequirements" : "io.k8s.api.core.v1.ResourceRequirements" ,
"io.k8s.kubernetes.pkg.apis.apps.v1beta1.RollingUpdateDeployment" : "io.k8s.api.apps.v1beta1.RollingUpdateDeployment" ,
"io.k8s.kubernetes.pkg.api.v1.NamespaceStatus" : "io.k8s.api.core.v1.NamespaceStatus" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.RunAsUserStrategyOptions" : "io.k8s.api.extensions.v1beta1.RunAsUserStrategyOptions" ,
"io.k8s.kubernetes.pkg.api.v1.Namespace" : "io.k8s.api.core.v1.Namespace" ,
"io.k8s.kubernetes.pkg.apis.authorization.v1.SubjectAccessReviewSpec" : "io.k8s.api.authorization.v1.SubjectAccessReviewSpec" ,
"io.k8s.kubernetes.pkg.apis.autoscaling.v2alpha1.HorizontalPodAutoscaler" : "io.k8s.api.autoscaling.v2alpha1.HorizontalPodAutoscaler" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.ReplicaSetCondition" : "io.k8s.api.extensions.v1beta1.ReplicaSetCondition" ,
"io.k8s.kubernetes.pkg.apis.autoscaling.v1.HorizontalPodAutoscalerStatus" : "io.k8s.api.autoscaling.v1.HorizontalPodAutoscalerStatus" ,
"io.k8s.kubernetes.pkg.apis.authentication.v1.TokenReviewStatus" : "io.k8s.api.authentication.v1.TokenReviewStatus" ,
"io.k8s.kubernetes.pkg.api.v1.PersistentVolume" : "io.k8s.api.core.v1.PersistentVolume" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.FSGroupStrategyOptions" : "io.k8s.api.extensions.v1beta1.FSGroupStrategyOptions" ,
"io.k8s.kubernetes.pkg.api.v1.PodSecurityContext" : "io.k8s.api.core.v1.PodSecurityContext" ,
"io.k8s.kubernetes.pkg.api.v1.PodTemplate" : "io.k8s.api.core.v1.PodTemplate" ,
"io.k8s.kubernetes.pkg.apis.authorization.v1.LocalSubjectAccessReview" : "io.k8s.api.authorization.v1.LocalSubjectAccessReview" ,
"io.k8s.kubernetes.pkg.api.v1.StorageOSVolumeSource" : "io.k8s.api.core.v1.StorageOSVolumeSource" ,
"io.k8s.kubernetes.pkg.api.v1.NodeSelectorTerm" : "io.k8s.api.core.v1.NodeSelectorTerm" ,
"io.k8s.kubernetes.pkg.apis.rbac.v1beta1.Role" : "io.k8s.api.rbac.v1beta1.Role" ,
"io.k8s.kubernetes.pkg.api.v1.ContainerStatus" : "io.k8s.api.core.v1.ContainerStatus" ,
"io.k8s.kubernetes.pkg.apis.authorization.v1.SubjectAccessReviewStatus" : "io.k8s.api.authorization.v1.SubjectAccessReviewStatus" ,
"io.k8s.kubernetes.pkg.apis.authentication.v1.TokenReviewSpec" : "io.k8s.api.authentication.v1.TokenReviewSpec" ,
"io.k8s.kubernetes.pkg.api.v1.ConfigMap" : "io.k8s.api.core.v1.ConfigMap" ,
"io.k8s.kubernetes.pkg.api.v1.ServiceStatus" : "io.k8s.api.core.v1.ServiceStatus" ,
"io.k8s.kubernetes.pkg.apis.authorization.v1beta1.SelfSubjectAccessReviewSpec" : "io.k8s.api.authorization.v1beta1.SelfSubjectAccessReviewSpec" ,
"io.k8s.kubernetes.pkg.api.v1.CinderVolumeSource" : "io.k8s.api.core.v1.CinderVolumeSource" ,
"io.k8s.kubernetes.pkg.apis.settings.v1alpha1.PodPresetSpec" : "io.k8s.api.settings.v1alpha1.PodPresetSpec" ,
"io.k8s.kubernetes.pkg.apis.authorization.v1beta1.NonResourceAttributes" : "io.k8s.api.authorization.v1beta1.NonResourceAttributes" ,
"io.k8s.kubernetes.pkg.api.v1.ContainerImage" : "io.k8s.api.core.v1.ContainerImage" ,
"io.k8s.kubernetes.pkg.api.v1.ReplicationControllerCondition" : "io.k8s.api.core.v1.ReplicationControllerCondition" ,
"io.k8s.kubernetes.pkg.api.v1.EmptyDirVolumeSource" : "io.k8s.api.core.v1.EmptyDirVolumeSource" ,
"io.k8s.kubernetes.pkg.apis.autoscaling.v1.HorizontalPodAutoscalerList" : "io.k8s.api.autoscaling.v1.HorizontalPodAutoscalerList" ,
"io.k8s.kubernetes.pkg.apis.batch.v1.JobList" : "io.k8s.api.batch.v1.JobList" ,
"io.k8s.kubernetes.pkg.api.v1.NFSVolumeSource" : "io.k8s.api.core.v1.NFSVolumeSource" ,
"io.k8s.kubernetes.pkg.api.v1.Pod" : "io.k8s.api.core.v1.Pod" ,
"io.k8s.kubernetes.pkg.api.v1.ObjectReference" : "io.k8s.api.core.v1.ObjectReference" ,
"io.k8s.kubernetes.pkg.apis.apps.v1beta1.Deployment" : "io.k8s.api.apps.v1beta1.Deployment" ,
"io.k8s.kubernetes.pkg.apis.storage.v1.StorageClassList" : "io.k8s.api.storage.v1.StorageClassList" ,
"io.k8s.kubernetes.pkg.api.v1.AttachedVolume" : "io.k8s.api.core.v1.AttachedVolume" ,
"io.k8s.kubernetes.pkg.api.v1.AWSElasticBlockStoreVolumeSource" : "io.k8s.api.core.v1.AWSElasticBlockStoreVolumeSource" ,
"io.k8s.kubernetes.pkg.apis.batch.v2alpha1.CronJobList" : "io.k8s.api.batch.v2alpha1.CronJobList" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.DeploymentSpec" : "io.k8s.api.extensions.v1beta1.DeploymentSpec" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.PodSecurityPolicyList" : "io.k8s.api.extensions.v1beta1.PodSecurityPolicyList" ,
"io.k8s.kubernetes.pkg.api.v1.PodAffinityTerm" : "io.k8s.api.core.v1.PodAffinityTerm" ,
"io.k8s.kubernetes.pkg.api.v1.HTTPHeader" : "io.k8s.api.core.v1.HTTPHeader" ,
"io.k8s.kubernetes.pkg.api.v1.ConfigMapKeySelector" : "io.k8s.api.core.v1.ConfigMapKeySelector" ,
"io.k8s.kubernetes.pkg.api.v1.SecretKeySelector" : "io.k8s.api.core.v1.SecretKeySelector" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.DeploymentList" : "io.k8s.api.extensions.v1beta1.DeploymentList" ,
"io.k8s.kubernetes.pkg.apis.authentication.v1.UserInfo" : "io.k8s.api.authentication.v1.UserInfo" ,
"io.k8s.kubernetes.pkg.api.v1.LoadBalancerIngress" : "io.k8s.api.core.v1.LoadBalancerIngress" ,
"io.k8s.kubernetes.pkg.api.v1.DaemonEndpoint" : "io.k8s.api.core.v1.DaemonEndpoint" ,
"io.k8s.kubernetes.pkg.api.v1.NodeSelectorRequirement" : "io.k8s.api.core.v1.NodeSelectorRequirement" ,
"io.k8s.kubernetes.pkg.apis.batch.v2alpha1.CronJobStatus" : "io.k8s.api.batch.v2alpha1.CronJobStatus" ,
"io.k8s.kubernetes.pkg.apis.autoscaling.v1.Scale" : "io.k8s.api.autoscaling.v1.Scale" ,
"io.k8s.kubernetes.pkg.api.v1.ScaleIOVolumeSource" : "io.k8s.api.core.v1.ScaleIOVolumeSource" ,
"io.k8s.kubernetes.pkg.api.v1.PodAntiAffinity" : "io.k8s.api.core.v1.PodAntiAffinity" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.PodSecurityPolicySpec" : "io.k8s.api.extensions.v1beta1.PodSecurityPolicySpec" ,
"io.k8s.kubernetes.pkg.apis.settings.v1alpha1.PodPresetList" : "io.k8s.api.settings.v1alpha1.PodPresetList" ,
"io.k8s.kubernetes.pkg.api.v1.NodeAffinity" : "io.k8s.api.core.v1.NodeAffinity" ,
"io.k8s.kubernetes.pkg.apis.apps.v1beta1.DeploymentCondition" : "io.k8s.api.apps.v1beta1.DeploymentCondition" ,
"io.k8s.kubernetes.pkg.api.v1.NodeSpec" : "io.k8s.api.core.v1.NodeSpec" ,
"io.k8s.kubernetes.pkg.apis.apps.v1beta1.StatefulSetStatus" : "io.k8s.api.apps.v1beta1.StatefulSetStatus" ,
"io.k8s.kubernetes.pkg.apis.admissionregistration.v1alpha1.RuleWithOperations" : "io.k8s.api.admissionregistration.v1alpha1.RuleWithOperations" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.IngressStatus" : "io.k8s.api.extensions.v1beta1.IngressStatus" ,
"io.k8s.kubernetes.pkg.api.v1.LimitRangeList" : "io.k8s.api.core.v1.LimitRangeList" ,
"io.k8s.kubernetes.pkg.api.v1.AzureDiskVolumeSource" : "io.k8s.api.core.v1.AzureDiskVolumeSource" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.ReplicaSetStatus" : "io.k8s.api.extensions.v1beta1.ReplicaSetStatus" ,
"io.k8s.kubernetes.pkg.api.v1.ComponentStatus" : "io.k8s.api.core.v1.ComponentStatus" ,
"io.k8s.kubernetes.pkg.apis.autoscaling.v1.HorizontalPodAutoscaler" : "io.k8s.api.autoscaling.v1.HorizontalPodAutoscaler" ,
"io.k8s.kubernetes.pkg.apis.networking.v1.NetworkPolicy" : "io.k8s.api.networking.v1.NetworkPolicy" ,
"io.k8s.kubernetes.pkg.apis.apps.v1beta1.RollbackConfig" : "io.k8s.api.apps.v1beta1.RollbackConfig" ,
"io.k8s.kubernetes.pkg.api.v1.NodeCondition" : "io.k8s.api.core.v1.NodeCondition" ,
"io.k8s.kubernetes.pkg.api.v1.DownwardAPIProjection" : "io.k8s.api.core.v1.DownwardAPIProjection" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.SELinuxStrategyOptions" : "io.k8s.api.extensions.v1beta1.SELinuxStrategyOptions" ,
"io.k8s.kubernetes.pkg.api.v1.NamespaceSpec" : "io.k8s.api.core.v1.NamespaceSpec" ,
"io.k8s.kubernetes.pkg.apis.certificates.v1beta1.CertificateSigningRequestSpec" : "io.k8s.api.certificates.v1beta1.CertificateSigningRequestSpec" ,
"io.k8s.kubernetes.pkg.api.v1.ServiceSpec" : "io.k8s.api.core.v1.ServiceSpec" ,
"io.k8s.kubernetes.pkg.apis.authorization.v1.SubjectAccessReview" : "io.k8s.api.authorization.v1.SubjectAccessReview" ,
"io.k8s.kubernetes.pkg.apis.apps.v1beta1.DeploymentList" : "io.k8s.api.apps.v1beta1.DeploymentList" ,
"io.k8s.kubernetes.pkg.api.v1.Toleration" : "io.k8s.api.core.v1.Toleration" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.NetworkPolicyList" : "io.k8s.api.extensions.v1beta1.NetworkPolicyList" ,
"io.k8s.kubernetes.pkg.apis.autoscaling.v2alpha1.PodsMetricSource" : "io.k8s.api.autoscaling.v2alpha1.PodsMetricSource" ,
"io.k8s.kubernetes.pkg.api.v1.EnvFromSource" : "io.k8s.api.core.v1.EnvFromSource" ,
"io.k8s.kubernetes.pkg.apis.autoscaling.v1.ScaleSpec" : "io.k8s.api.autoscaling.v1.ScaleSpec" ,
"io.k8s.kubernetes.pkg.api.v1.PodTemplateList" : "io.k8s.api.core.v1.PodTemplateList" ,
"io.k8s.kubernetes.pkg.apis.autoscaling.v2alpha1.HorizontalPodAutoscalerSpec" : "io.k8s.api.autoscaling.v2alpha1.HorizontalPodAutoscalerSpec" ,
"io.k8s.kubernetes.pkg.api.v1.SecretProjection" : "io.k8s.api.core.v1.SecretProjection" ,
"io.k8s.kubernetes.pkg.api.v1.ResourceFieldSelector" : "io.k8s.api.core.v1.ResourceFieldSelector" ,
"io.k8s.kubernetes.pkg.api.v1.PersistentVolumeSpec" : "io.k8s.api.core.v1.PersistentVolumeSpec" ,
"io.k8s.kubernetes.pkg.api.v1.ConfigMapVolumeSource" : "io.k8s.api.core.v1.ConfigMapVolumeSource" ,
"io.k8s.kubernetes.pkg.apis.autoscaling.v2alpha1.HorizontalPodAutoscalerList" : "io.k8s.api.autoscaling.v2alpha1.HorizontalPodAutoscalerList" ,
"io.k8s.kubernetes.pkg.apis.authentication.v1beta1.TokenReviewStatus" : "io.k8s.api.authentication.v1beta1.TokenReviewStatus" ,
"io.k8s.kubernetes.pkg.apis.networking.v1.NetworkPolicyList" : "io.k8s.api.networking.v1.NetworkPolicyList" ,
"io.k8s.kubernetes.pkg.api.v1.Endpoints" : "io.k8s.api.core.v1.Endpoints" ,
"io.k8s.kubernetes.pkg.api.v1.LimitRangeItem" : "io.k8s.api.core.v1.LimitRangeItem" ,
"io.k8s.kubernetes.pkg.api.v1.ServiceAccount" : "io.k8s.api.core.v1.ServiceAccount" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.ScaleSpec" : "io.k8s.api.extensions.v1beta1.ScaleSpec" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.IngressTLS" : "io.k8s.api.extensions.v1beta1.IngressTLS" ,
"io.k8s.kubernetes.pkg.apis.batch.v2alpha1.CronJob" : "io.k8s.api.batch.v2alpha1.CronJob" ,
"io.k8s.kubernetes.pkg.apis.rbac.v1alpha1.Subject" : "io.k8s.api.rbac.v1alpha1.Subject" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.DaemonSetStatus" : "io.k8s.api.extensions.v1beta1.DaemonSetStatus" ,
"io.k8s.kubernetes.pkg.apis.policy.v1beta1.PodDisruptionBudgetList" : "io.k8s.api.policy.v1beta1.PodDisruptionBudgetList" ,
"io.k8s.kubernetes.pkg.api.v1.VsphereVirtualDiskVolumeSource" : "io.k8s.api.core.v1.VsphereVirtualDiskVolumeSource" ,
"io.k8s.kubernetes.pkg.apis.rbac.v1alpha1.RoleRef" : "io.k8s.api.rbac.v1alpha1.RoleRef" ,
"io.k8s.kubernetes.pkg.api.v1.PortworxVolumeSource" : "io.k8s.api.core.v1.PortworxVolumeSource" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.ReplicaSetList" : "io.k8s.api.extensions.v1beta1.ReplicaSetList" ,
"io.k8s.kubernetes.pkg.api.v1.VolumeProjection" : "io.k8s.api.core.v1.VolumeProjection" ,
"io.k8s.kubernetes.pkg.apis.storage.v1beta1.StorageClass" : "io.k8s.api.storage.v1beta1.StorageClass" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.ReplicaSet" : "io.k8s.api.extensions.v1beta1.ReplicaSet" ,
"io.k8s.kubernetes.pkg.apis.apps.v1beta1.DeploymentRollback" : "io.k8s.api.apps.v1beta1.DeploymentRollback" ,
"io.k8s.kubernetes.pkg.apis.rbac.v1alpha1.RoleBinding" : "io.k8s.api.rbac.v1alpha1.RoleBinding" ,
"io.k8s.kubernetes.pkg.api.v1.AzureFileVolumeSource" : "io.k8s.api.core.v1.AzureFileVolumeSource" ,
"io.k8s.kubernetes.pkg.apis.policy.v1beta1.PodDisruptionBudgetStatus" : "io.k8s.api.policy.v1beta1.PodDisruptionBudgetStatus" ,
"io.k8s.kubernetes.pkg.apis.authentication.v1beta1.TokenReviewSpec" : "io.k8s.api.authentication.v1beta1.TokenReviewSpec" ,
"io.k8s.kubernetes.pkg.api.v1.EndpointsList" : "io.k8s.api.core.v1.EndpointsList" ,
"io.k8s.kubernetes.pkg.api.v1.ConfigMapEnvSource" : "io.k8s.api.core.v1.ConfigMapEnvSource" ,
"io.k8s.kubernetes.pkg.apis.batch.v2alpha1.JobTemplateSpec" : "io.k8s.api.batch.v2alpha1.JobTemplateSpec" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.DaemonSetUpdateStrategy" : "io.k8s.api.extensions.v1beta1.DaemonSetUpdateStrategy" ,
"io.k8s.kubernetes.pkg.apis.authorization.v1beta1.SubjectAccessReviewSpec" : "io.k8s.api.authorization.v1beta1.SubjectAccessReviewSpec" ,
"io.k8s.kubernetes.pkg.api.v1.LocalVolumeSource" : "io.k8s.api.core.v1.LocalVolumeSource" ,
"io.k8s.kubernetes.pkg.api.v1.ContainerState" : "io.k8s.api.core.v1.ContainerState" ,
"io.k8s.kubernetes.pkg.api.v1.Service" : "io.k8s.api.core.v1.Service" ,
"io.k8s.kubernetes.pkg.api.v1.ExecAction" : "io.k8s.api.core.v1.ExecAction" ,
"io.k8s.kubernetes.pkg.api.v1.Taint" : "io.k8s.api.core.v1.Taint" ,
"io.k8s.kubernetes.pkg.apis.rbac.v1beta1.Subject" : "io.k8s.api.rbac.v1beta1.Subject" ,
"io.k8s.kubernetes.pkg.apis.authorization.v1beta1.SubjectAccessReviewStatus" : "io.k8s.api.authorization.v1beta1.SubjectAccessReviewStatus" ,
"io.k8s.kubernetes.pkg.apis.rbac.v1beta1.ClusterRoleBindingList" : "io.k8s.api.rbac.v1beta1.ClusterRoleBindingList" ,
"io.k8s.kubernetes.pkg.api.v1.DownwardAPIVolumeSource" : "io.k8s.api.core.v1.DownwardAPIVolumeSource" ,
"io.k8s.kubernetes.pkg.apis.batch.v1.JobStatus" : "io.k8s.api.batch.v1.JobStatus" ,
"io.k8s.kubernetes.pkg.api.v1.ResourceQuotaStatus" : "io.k8s.api.core.v1.ResourceQuotaStatus" ,
"io.k8s.kubernetes.pkg.api.v1.PersistentVolumeStatus" : "io.k8s.api.core.v1.PersistentVolumeStatus" ,
"io.k8s.kubernetes.pkg.api.v1.PersistentVolumeClaim" : "io.k8s.api.core.v1.PersistentVolumeClaim" ,
"io.k8s.kubernetes.pkg.api.v1.NodeDaemonEndpoints" : "io.k8s.api.core.v1.NodeDaemonEndpoints" ,
"io.k8s.kubernetes.pkg.api.v1.EnvVar" : "io.k8s.api.core.v1.EnvVar" ,
"io.k8s.kubernetes.pkg.api.v1.SecretVolumeSource" : "io.k8s.api.core.v1.SecretVolumeSource" ,
"io.k8s.kubernetes.pkg.api.v1.EnvVarSource" : "io.k8s.api.core.v1.EnvVarSource" ,
"io.k8s.kubernetes.pkg.apis.apps.v1beta1.RollingUpdateStatefulSetStrategy" : "io.k8s.api.apps.v1beta1.RollingUpdateStatefulSetStrategy" ,
"io.k8s.kubernetes.pkg.apis.rbac.v1beta1.ClusterRole" : "io.k8s.api.rbac.v1beta1.ClusterRole" ,
"io.k8s.kubernetes.pkg.apis.admissionregistration.v1alpha1.Initializer" : "io.k8s.api.admissionregistration.v1alpha1.Initializer" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.DeploymentStrategy" : "io.k8s.api.extensions.v1beta1.DeploymentStrategy" ,
"io.k8s.kubernetes.pkg.apis.apps.v1beta1.ScaleSpec" : "io.k8s.api.apps.v1beta1.ScaleSpec" ,
"io.k8s.kubernetes.pkg.apis.settings.v1alpha1.PodPreset" : "io.k8s.api.settings.v1alpha1.PodPreset" ,
"io.k8s.kubernetes.pkg.api.v1.Probe" : "io.k8s.api.core.v1.Probe" ,
"io.k8s.kubernetes.pkg.api.v1.NamespaceList" : "io.k8s.api.core.v1.NamespaceList" ,
"io.k8s.kubernetes.pkg.api.v1.QuobyteVolumeSource" : "io.k8s.api.core.v1.QuobyteVolumeSource" ,
"io.k8s.kubernetes.pkg.api.v1.NodeList" : "io.k8s.api.core.v1.NodeList" ,
"io.k8s.kubernetes.pkg.apis.extensions.v1beta1.RollingUpdateDaemonSet" : "io.k8s.api.extensions.v1beta1.RollingUpdateDaemonSet" ,
"io.k8s.kubernetes.pkg.api.v1.LimitRange" : "io.k8s.api.core.v1.LimitRange" ,
2017-02-02 00:05:55 +00:00
}
for k , v := range compatibilityMap {
if _ , found := s . Definitions [ v ] ; ! found {
continue
}
s . Definitions [ k ] = spec . Schema {
SchemaProps : spec . SchemaProps {
Ref : spec . MustCreateRef ( "#/definitions/" + openapi . EscapeJsonPointer ( v ) ) ,
Description : fmt . Sprintf ( "Deprecated. Please use %s instead." , v ) ,
} ,
}
}
return s , nil
}