Update ingress godeps

This commit is contained in:
Manuel de Brito Fontes 2016-08-10 14:53:55 -04:00
parent d43021b3f1
commit 28db8fb16d
1068 changed files with 461467 additions and 117300 deletions

View file

@ -496,21 +496,34 @@ func (f *DeltaFIFO) Replace(list []interface{}, resourceVersion string) error {
// Resync will send a sync event for each item
func (f *DeltaFIFO) Resync() error {
f.lock.RLock()
defer f.lock.RUnlock()
for _, k := range f.knownObjects.ListKeys() {
obj, exists, err := f.knownObjects.GetByKey(k)
if err != nil {
glog.Errorf("Unexpected error %v during lookup of key %v, unable to queue object for sync", err, k)
continue
} else if !exists {
glog.Infof("Key %v does not exist in known objects store, unable to queue object for sync", k)
continue
var keys []string
func() {
f.lock.RLock()
defer f.lock.RUnlock()
keys = f.knownObjects.ListKeys()
}()
for _, k := range keys {
if err := f.syncKey(k); err != nil {
return err
}
}
return nil
}
if err := f.queueActionLocked(Sync, obj); err != nil {
return fmt.Errorf("couldn't queue object: %v", err)
}
func (f *DeltaFIFO) syncKey(key string) error {
f.lock.Lock()
defer f.lock.Unlock()
obj, exists, err := f.knownObjects.GetByKey(key)
if err != nil {
glog.Errorf("Unexpected error %v during lookup of key %v, unable to queue object for sync", err, key)
return nil
} else if !exists {
glog.Infof("Key %v does not exist in known objects store, unable to queue object for sync", key)
return nil
}
if err := f.queueActionLocked(Sync, obj); err != nil {
return fmt.Errorf("couldn't queue object: %v", err)
}
return nil
}

View file

@ -21,7 +21,7 @@ import (
"time"
"github.com/golang/glog"
"k8s.io/kubernetes/pkg/util"
"k8s.io/kubernetes/pkg/util/clock"
)
// ExpirationCache implements the store interface
@ -38,7 +38,7 @@ import (
type ExpirationCache struct {
cacheStorage ThreadSafeStore
keyFunc KeyFunc
clock util.Clock
clock clock.Clock
expirationPolicy ExpirationPolicy
// expirationLock is a write lock used to guarantee that we don't clobber
// newly inserted objects because of a stale expiration timestamp comparison
@ -58,7 +58,7 @@ type TTLPolicy struct {
Ttl time.Duration
// Clock used to calculate ttl expiration
Clock util.Clock
Clock clock.Clock
}
// IsExpired returns true if the given object is older than the ttl, or it can't
@ -73,7 +73,7 @@ type timestampedEntry struct {
timestamp time.Time
}
// getTimestampedEntry returnes the timestampedEntry stored under the given key.
// getTimestampedEntry returns the timestampedEntry stored under the given key.
func (c *ExpirationCache) getTimestampedEntry(key string) (*timestampedEntry, bool) {
item, _ := c.cacheStorage.Get(key)
if tsEntry, ok := item.(*timestampedEntry); ok {
@ -202,7 +202,7 @@ func NewTTLStore(keyFunc KeyFunc, ttl time.Duration) Store {
return &ExpirationCache{
cacheStorage: NewThreadSafeStore(Indexers{}, Indices{}),
keyFunc: keyFunc,
clock: util.RealClock{},
expirationPolicy: &TTLPolicy{ttl, util.RealClock{}},
clock: clock.RealClock{},
expirationPolicy: &TTLPolicy{ttl, clock.RealClock{}},
}
}

View file

@ -17,7 +17,7 @@ limitations under the License.
package cache
import (
"k8s.io/kubernetes/pkg/util"
"k8s.io/kubernetes/pkg/util/clock"
"k8s.io/kubernetes/pkg/util/sets"
)
@ -43,7 +43,7 @@ func (p *FakeExpirationPolicy) IsExpired(obj *timestampedEntry) bool {
return !p.NeverExpire.Has(key)
}
func NewFakeExpirationStore(keyFunc KeyFunc, deletedKeys chan<- string, expirationPolicy ExpirationPolicy, cacheClock util.Clock) Store {
func NewFakeExpirationStore(keyFunc KeyFunc, deletedKeys chan<- string, expirationPolicy ExpirationPolicy, cacheClock clock.Clock) Store {
cacheStorage := NewThreadSafeStore(Indexers{}, Indices{})
return &ExpirationCache{
cacheStorage: &fakeThreadSafeMap{cacheStorage, deletedKeys},

View file

@ -55,6 +55,9 @@ func IndexFuncToKeyFuncAdapter(indexFunc IndexFunc) KeyFunc {
if len(indexKeys) > 1 {
return "", fmt.Errorf("too many keys: %v", indexKeys)
}
if len(indexKeys) == 0 {
return "", fmt.Errorf("unexpected empty indexKeys")
}
return indexKeys[0], nil
}
}

View file

@ -21,10 +21,13 @@ import (
"github.com/golang/glog"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/errors"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/apis/apps"
"k8s.io/kubernetes/pkg/apis/batch"
"k8s.io/kubernetes/pkg/apis/certificates"
"k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/apis/policy"
"k8s.io/kubernetes/pkg/labels"
)
@ -47,13 +50,9 @@ type StoreToPodLister struct {
// Please note that selector is filtering among the pods that have gotten into
// the store; there may have been some filtering that already happened before
// that.
//
// TODO: converge on the interface in pkg/client.
// We explicitly don't return api.PodList, to avoid expensive allocations, which
// in most cases are unnecessary.
func (s *StoreToPodLister) List(selector labels.Selector) (pods []*api.Pod, err error) {
// TODO: it'd be great to just call
// s.Pods(api.NamespaceAll).List(selector), however then we'd have to
// remake the list.Items as a []*api.Pod. So leave this separate for
// now.
for _, m := range s.Indexer.List() {
pod := m.(*api.Pod)
if selector.Matches(labels.Set(pod.Labels)) {
@ -76,14 +75,14 @@ type storePodsNamespacer struct {
// Please note that selector is filtering among the pods that have gotten into
// the store; there may have been some filtering that already happened before
// that.
func (s storePodsNamespacer) List(selector labels.Selector) (api.PodList, error) {
pods := api.PodList{}
// We explicitly don't return api.PodList, to avoid expensive allocations, which
// in most cases are unnecessary.
func (s storePodsNamespacer) List(selector labels.Selector) (pods []*api.Pod, err error) {
if s.namespace == api.NamespaceAll {
for _, m := range s.indexer.List() {
pod := m.(*api.Pod)
if selector.Matches(labels.Set(pod.Labels)) {
pods.Items = append(pods.Items, *pod)
pods = append(pods, pod)
}
}
return pods, nil
@ -97,7 +96,7 @@ func (s storePodsNamespacer) List(selector labels.Selector) (api.PodList, error)
for _, m := range s.indexer.List() {
pod := m.(*api.Pod)
if s.namespace == pod.Namespace && selector.Matches(labels.Set(pod.Labels)) {
pods.Items = append(pods.Items, *pod)
pods = append(pods, pod)
}
}
return pods, nil
@ -105,12 +104,23 @@ func (s storePodsNamespacer) List(selector labels.Selector) (api.PodList, error)
for _, m := range items {
pod := m.(*api.Pod)
if selector.Matches(labels.Set(pod.Labels)) {
pods.Items = append(pods.Items, *pod)
pods = append(pods, pod)
}
}
return pods, nil
}
func (s storePodsNamespacer) Get(name string) (*api.Pod, error) {
obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.NewNotFound(api.Resource("pod"), name)
}
return obj.(*api.Pod), nil
}
// Exists returns true if a pod matching the namespace/name of the given pod exists in the store.
func (s *StoreToPodLister) Exists(pod *api.Pod) (bool, error) {
_, exists, err := s.Indexer.Get(pod)
@ -151,11 +161,11 @@ type storeToNodeConditionLister struct {
}
// List returns a list of nodes that match the conditions defined by the predicate functions in the storeToNodeConditionLister.
func (s storeToNodeConditionLister) List() (nodes api.NodeList, err error) {
func (s storeToNodeConditionLister) List() (nodes []*api.Node, err error) {
for _, m := range s.store.List() {
node := m.(*api.Node)
if s.predicate(node) {
nodes.Items = append(nodes.Items, *node)
nodes = append(nodes, node)
} else {
glog.V(5).Infof("Node %s matches none of the conditions", node.Name)
}
@ -230,6 +240,17 @@ func (s storeReplicationControllersNamespacer) List(selector labels.Selector) ([
return controllers, nil
}
func (s storeReplicationControllersNamespacer) Get(name string) (*api.ReplicationController, error) {
obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.NewNotFound(api.Resource("replicationcontroller"), name)
}
return obj.(*api.ReplicationController), nil
}
// GetPodControllers returns a list of replication controllers managing a pod. Returns an error only if no matching controllers are found.
func (s *StoreToReplicationControllerLister) GetPodControllers(pod *api.Pod) (controllers []api.ReplicationController, err error) {
var selector labels.Selector
@ -248,11 +269,10 @@ func (s *StoreToReplicationControllerLister) GetPodControllers(pod *api.Pod) (co
for _, m := range items {
rc = *m.(*api.ReplicationController)
labelSet := labels.Set(rc.Spec.Selector)
selector = labels.Set(rc.Spec.Selector).AsSelector()
selector = labels.Set(rc.Spec.Selector).AsSelectorPreValidated()
// If an rc with a nil or empty selector creeps in, it should match nothing, not everything.
if labelSet.AsSelector().Empty() || !selector.Matches(labels.Set(pod.Labels)) {
if selector.Empty() || !selector.Matches(labels.Set(pod.Labels)) {
continue
}
controllers = append(controllers, rc)
@ -358,6 +378,17 @@ func (s storeReplicaSetsNamespacer) List(selector labels.Selector) (rss []extens
return
}
func (s storeReplicaSetsNamespacer) Get(name string) (*extensions.ReplicaSet, error) {
obj, exists, err := s.store.GetByKey(s.namespace + "/" + name)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.NewNotFound(extensions.Resource("replicaset"), name)
}
return obj.(*extensions.ReplicaSet), nil
}
func (s *StoreToReplicaSetLister) ReplicaSets(namespace string) storeReplicaSetsNamespacer {
return storeReplicaSetsNamespacer{s.Store, namespace}
}
@ -481,7 +512,7 @@ func (s *StoreToServiceLister) GetPodServices(pod *api.Pod) (services []api.Serv
// services with nil selectors match nothing, not everything.
continue
}
selector = labels.Set(service.Spec.Selector).AsSelector()
selector = labels.Set(service.Spec.Selector).AsSelectorPreValidated()
if selector.Matches(labels.Set(pod.Labels)) {
services = append(services, service)
}
@ -670,3 +701,83 @@ func (s *StoreToPetSetLister) GetPodPetSets(pod *api.Pod) (psList []apps.PetSet,
}
return
}
// StoreToCertificateRequestLister gives a store List and Exists methods. The store must contain only CertificateRequests.
type StoreToCertificateRequestLister struct {
Store
}
// Exists checks if the given csr exists in the store.
func (s *StoreToCertificateRequestLister) Exists(csr *certificates.CertificateSigningRequest) (bool, error) {
_, exists, err := s.Store.Get(csr)
if err != nil {
return false, err
}
return exists, nil
}
// StoreToCertificateRequestLister lists all csrs in the store.
func (s *StoreToCertificateRequestLister) List() (csrs certificates.CertificateSigningRequestList, err error) {
for _, c := range s.Store.List() {
csrs.Items = append(csrs.Items, *(c.(*certificates.CertificateSigningRequest)))
}
return csrs, nil
}
// IndexerToNamespaceLister gives an Indexer List method
type IndexerToNamespaceLister struct {
Indexer
}
// List returns a list of namespaces
func (i *IndexerToNamespaceLister) List(selector labels.Selector) (namespaces []*api.Namespace, err error) {
for _, m := range i.Indexer.List() {
namespace := m.(*api.Namespace)
if selector.Matches(labels.Set(namespace.Labels)) {
namespaces = append(namespaces, namespace)
}
}
return namespaces, nil
}
type StoreToPodDisruptionBudgetLister struct {
Store
}
// GetPodPodDisruptionBudgets returns a list of PodDisruptionBudgets matching a pod. Returns an error only if no matching PodDisruptionBudgets are found.
func (s *StoreToPodDisruptionBudgetLister) GetPodPodDisruptionBudgets(pod *api.Pod) (pdbList []policy.PodDisruptionBudget, err error) {
var selector labels.Selector
if len(pod.Labels) == 0 {
err = fmt.Errorf("no PodDisruptionBudgets found for pod %v because it has no labels", pod.Name)
return
}
for _, m := range s.Store.List() {
pdb, ok := m.(*policy.PodDisruptionBudget)
if !ok {
glog.Errorf("Unexpected: %v is not a PodDisruptionBudget", m)
continue
}
if pdb.Namespace != pod.Namespace {
continue
}
selector, err = unversioned.LabelSelectorAsSelector(pdb.Spec.Selector)
if err != nil {
glog.Warningf("invalid selector: %v", err)
// TODO(mml): add an event to the PDB
continue
}
// If a PDB with a nil or empty selector creeps in, it should match nothing, not everything.
if selector.Empty() || !selector.Matches(labels.Set(pod.Labels)) {
continue
}
pdbList = append(pdbList, *pdb)
}
if len(pdbList) == 0 {
err = fmt.Errorf("could not find PodDisruptionBudget for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels)
}
return
}

View file

@ -69,8 +69,6 @@ type Reflector struct {
resyncPeriod time.Duration
// now() returns current time - exposed for testing purposes
now func() time.Time
// nextResync is approximate time of next resync (0 if not scheduled)
nextResync time.Time
// lastSyncResourceVersion is the resource version token last
// observed when doing a sync with the underlying store
// it is thread safe, but not synchronized with the underlying store
@ -164,7 +162,7 @@ func hasPackage(file string, ignoredPackages []string) bool {
return false
}
// trimPackagePrefix reduces dulpicate values off the front of a package name.
// trimPackagePrefix reduces duplicate values off the front of a package name.
func trimPackagePrefix(file string) string {
if l := strings.LastIndex(file, "k8s.io/kubernetes/pkg/"); l >= 0 {
return file[l+len("k8s.io/kubernetes/"):]
@ -234,14 +232,12 @@ var (
// required, and a cleanup function.
func (r *Reflector) resyncChan() (<-chan time.Time, func() bool) {
if r.resyncPeriod == 0 {
r.nextResync = time.Time{}
return neverExitWatch, func() bool { return false }
}
// The cleanup function is required: imagine the scenario where watches
// always fail so we end up listing frequently. Then, if we don't
// manually stop the timer, we could end up with many timers active
// concurrently.
r.nextResync = r.now().Add(r.resyncPeriod)
t := time.NewTimer(r.resyncPeriod)
return t.C, t.Stop
}
@ -285,7 +281,7 @@ func (r *Reflector) ListAndWatch(stopCh <-chan struct{}) error {
case <-stopCh:
return
}
glog.V(4).Infof("%s: next resync planned for %#v, forcing now", r.name, r.nextResync)
glog.V(4).Infof("%s: forcing resync", r.name)
if err := r.store.Resync(); err != nil {
resyncerrc <- err
return

View file

@ -151,7 +151,7 @@ func (c *threadSafeMap) Index(indexName string, obj interface{}) ([]interface{},
returnKeySet := sets.String{}
for _, indexKey := range indexKeys {
set := index[indexKey]
for _, key := range set.List() {
for _, key := range set.UnsortedList() {
returnKeySet.Insert(key)
}
}

View file

@ -18,6 +18,8 @@ package internalclientset
import (
"github.com/golang/glog"
unversionedauthentication "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/authentication/unversioned"
unversionedauthorization "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/authorization/unversioned"
unversionedautoscaling "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/autoscaling/unversioned"
unversionedbatch "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/batch/unversioned"
unversionedcertificates "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/certificates/unversioned"
@ -32,11 +34,13 @@ import (
type Interface interface {
Discovery() discovery.DiscoveryInterface
Core() unversionedcore.CoreInterface
Extensions() unversionedextensions.ExtensionsInterface
Authentication() unversionedauthentication.AuthenticationInterface
Authorization() unversionedauthorization.AuthorizationInterface
Autoscaling() unversionedautoscaling.AutoscalingInterface
Batch() unversionedbatch.BatchInterface
Rbac() unversionedrbac.RbacInterface
Certificates() unversionedcertificates.CertificatesInterface
Extensions() unversionedextensions.ExtensionsInterface
Rbac() unversionedrbac.RbacInterface
}
// Clientset contains the clients for groups. Each group has exactly one
@ -44,11 +48,13 @@ type Interface interface {
type Clientset struct {
*discovery.DiscoveryClient
*unversionedcore.CoreClient
*unversionedextensions.ExtensionsClient
*unversionedauthentication.AuthenticationClient
*unversionedauthorization.AuthorizationClient
*unversionedautoscaling.AutoscalingClient
*unversionedbatch.BatchClient
*unversionedrbac.RbacClient
*unversionedcertificates.CertificatesClient
*unversionedextensions.ExtensionsClient
*unversionedrbac.RbacClient
}
// Core retrieves the CoreClient
@ -59,12 +65,20 @@ func (c *Clientset) Core() unversionedcore.CoreInterface {
return c.CoreClient
}
// Extensions retrieves the ExtensionsClient
func (c *Clientset) Extensions() unversionedextensions.ExtensionsInterface {
// Authentication retrieves the AuthenticationClient
func (c *Clientset) Authentication() unversionedauthentication.AuthenticationInterface {
if c == nil {
return nil
}
return c.ExtensionsClient
return c.AuthenticationClient
}
// Authorization retrieves the AuthorizationClient
func (c *Clientset) Authorization() unversionedauthorization.AuthorizationInterface {
if c == nil {
return nil
}
return c.AuthorizationClient
}
// Autoscaling retrieves the AutoscalingClient
@ -83,14 +97,6 @@ func (c *Clientset) Batch() unversionedbatch.BatchInterface {
return c.BatchClient
}
// Rbac retrieves the RbacClient
func (c *Clientset) Rbac() unversionedrbac.RbacInterface {
if c == nil {
return nil
}
return c.RbacClient
}
// Certificates retrieves the CertificatesClient
func (c *Clientset) Certificates() unversionedcertificates.CertificatesInterface {
if c == nil {
@ -99,6 +105,22 @@ func (c *Clientset) Certificates() unversionedcertificates.CertificatesInterface
return c.CertificatesClient
}
// Extensions retrieves the ExtensionsClient
func (c *Clientset) Extensions() unversionedextensions.ExtensionsInterface {
if c == nil {
return nil
}
return c.ExtensionsClient
}
// Rbac retrieves the RbacClient
func (c *Clientset) Rbac() unversionedrbac.RbacInterface {
if c == nil {
return nil
}
return c.RbacClient
}
// Discovery retrieves the DiscoveryClient
func (c *Clientset) Discovery() discovery.DiscoveryInterface {
return c.DiscoveryClient
@ -116,7 +138,11 @@ func NewForConfig(c *restclient.Config) (*Clientset, error) {
if err != nil {
return nil, err
}
clientset.ExtensionsClient, err = unversionedextensions.NewForConfig(&configShallowCopy)
clientset.AuthenticationClient, err = unversionedauthentication.NewForConfig(&configShallowCopy)
if err != nil {
return nil, err
}
clientset.AuthorizationClient, err = unversionedauthorization.NewForConfig(&configShallowCopy)
if err != nil {
return nil, err
}
@ -128,11 +154,15 @@ func NewForConfig(c *restclient.Config) (*Clientset, error) {
if err != nil {
return nil, err
}
clientset.RbacClient, err = unversionedrbac.NewForConfig(&configShallowCopy)
clientset.CertificatesClient, err = unversionedcertificates.NewForConfig(&configShallowCopy)
if err != nil {
return nil, err
}
clientset.CertificatesClient, err = unversionedcertificates.NewForConfig(&configShallowCopy)
clientset.ExtensionsClient, err = unversionedextensions.NewForConfig(&configShallowCopy)
if err != nil {
return nil, err
}
clientset.RbacClient, err = unversionedrbac.NewForConfig(&configShallowCopy)
if err != nil {
return nil, err
}
@ -150,11 +180,13 @@ func NewForConfig(c *restclient.Config) (*Clientset, error) {
func NewForConfigOrDie(c *restclient.Config) *Clientset {
var clientset Clientset
clientset.CoreClient = unversionedcore.NewForConfigOrDie(c)
clientset.ExtensionsClient = unversionedextensions.NewForConfigOrDie(c)
clientset.AuthenticationClient = unversionedauthentication.NewForConfigOrDie(c)
clientset.AuthorizationClient = unversionedauthorization.NewForConfigOrDie(c)
clientset.AutoscalingClient = unversionedautoscaling.NewForConfigOrDie(c)
clientset.BatchClient = unversionedbatch.NewForConfigOrDie(c)
clientset.RbacClient = unversionedrbac.NewForConfigOrDie(c)
clientset.CertificatesClient = unversionedcertificates.NewForConfigOrDie(c)
clientset.ExtensionsClient = unversionedextensions.NewForConfigOrDie(c)
clientset.RbacClient = unversionedrbac.NewForConfigOrDie(c)
clientset.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c)
return &clientset
@ -164,11 +196,13 @@ func NewForConfigOrDie(c *restclient.Config) *Clientset {
func New(c *restclient.RESTClient) *Clientset {
var clientset Clientset
clientset.CoreClient = unversionedcore.New(c)
clientset.ExtensionsClient = unversionedextensions.New(c)
clientset.AuthenticationClient = unversionedauthentication.New(c)
clientset.AuthorizationClient = unversionedauthorization.New(c)
clientset.AutoscalingClient = unversionedautoscaling.New(c)
clientset.BatchClient = unversionedbatch.New(c)
clientset.RbacClient = unversionedrbac.New(c)
clientset.CertificatesClient = unversionedcertificates.New(c)
clientset.ExtensionsClient = unversionedextensions.New(c)
clientset.RbacClient = unversionedrbac.New(c)
clientset.DiscoveryClient = discovery.NewDiscoveryClient(c)
return &clientset

View file

@ -23,6 +23,7 @@ import (
_ "k8s.io/kubernetes/pkg/api/install"
"k8s.io/kubernetes/pkg/apimachinery/registered"
_ "k8s.io/kubernetes/pkg/apis/apps/install"
_ "k8s.io/kubernetes/pkg/apis/authentication/install"
_ "k8s.io/kubernetes/pkg/apis/authorization/install"
_ "k8s.io/kubernetes/pkg/apis/autoscaling/install"
_ "k8s.io/kubernetes/pkg/apis/batch/install"

View file

@ -0,0 +1,101 @@
/*
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 unversioned
import (
api "k8s.io/kubernetes/pkg/api"
registered "k8s.io/kubernetes/pkg/apimachinery/registered"
restclient "k8s.io/kubernetes/pkg/client/restclient"
)
type AuthenticationInterface interface {
GetRESTClient() *restclient.RESTClient
TokenReviewsGetter
}
// AuthenticationClient is used to interact with features provided by the Authentication group.
type AuthenticationClient struct {
*restclient.RESTClient
}
func (c *AuthenticationClient) TokenReviews() TokenReviewInterface {
return newTokenReviews(c)
}
// NewForConfig creates a new AuthenticationClient for the given config.
func NewForConfig(c *restclient.Config) (*AuthenticationClient, error) {
config := *c
if err := setConfigDefaults(&config); err != nil {
return nil, err
}
client, err := restclient.RESTClientFor(&config)
if err != nil {
return nil, err
}
return &AuthenticationClient{client}, nil
}
// NewForConfigOrDie creates a new AuthenticationClient for the given config and
// panics if there is an error in the config.
func NewForConfigOrDie(c *restclient.Config) *AuthenticationClient {
client, err := NewForConfig(c)
if err != nil {
panic(err)
}
return client
}
// New creates a new AuthenticationClient for the given RESTClient.
func New(c *restclient.RESTClient) *AuthenticationClient {
return &AuthenticationClient{c}
}
func setConfigDefaults(config *restclient.Config) error {
// if authentication group is not registered, return an error
g, err := registered.Group("authentication.k8s.io")
if err != nil {
return err
}
config.APIPath = "/apis"
if config.UserAgent == "" {
config.UserAgent = restclient.DefaultKubernetesUserAgent()
}
// TODO: Unconditionally set the config.Version, until we fix the config.
//if config.Version == "" {
copyGroupVersion := g.GroupVersion
config.GroupVersion = &copyGroupVersion
//}
config.NegotiatedSerializer = api.Codecs
if config.QPS == 0 {
config.QPS = 5
}
if config.Burst == 0 {
config.Burst = 10
}
return nil
}
// GetRESTClient returns a RESTClient that is used to communicate
// with API server by this client implementation.
func (c *AuthenticationClient) GetRESTClient() *restclient.RESTClient {
if c == nil {
return nil
}
return c.RESTClient
}

View file

@ -0,0 +1,20 @@
/*
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.
*/
// This package is generated by client-gen with the default arguments.
// This package has the automatically generated typed clients.
package unversioned

View file

@ -0,0 +1,35 @@
/*
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 unversioned
import (
authenticationapi "k8s.io/kubernetes/pkg/apis/authentication"
)
type TokenReviewExpansion interface {
Create(tokenReview *authenticationapi.TokenReview) (result *authenticationapi.TokenReview, err error)
}
func (c *tokenReviews) Create(tokenReview *authenticationapi.TokenReview) (result *authenticationapi.TokenReview, err error) {
result = &authenticationapi.TokenReview{}
err = c.client.Post().
Resource("tokenreviews").
Body(tokenReview).
Do().
Into(result)
return
}

View file

@ -0,0 +1,40 @@
/*
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 unversioned
// TokenReviewsGetter has a method to return a TokenReviewInterface.
// A group's client should implement this interface.
type TokenReviewsGetter interface {
TokenReviews() TokenReviewInterface
}
// TokenReviewInterface has methods to work with TokenReview resources.
type TokenReviewInterface interface {
TokenReviewExpansion
}
// tokenReviews implements TokenReviewInterface
type tokenReviews struct {
client *AuthenticationClient
}
// newTokenReviews returns a TokenReviews
func newTokenReviews(c *AuthenticationClient) *tokenReviews {
return &tokenReviews{
client: c,
}
}

View file

@ -0,0 +1,101 @@
/*
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 unversioned
import (
api "k8s.io/kubernetes/pkg/api"
registered "k8s.io/kubernetes/pkg/apimachinery/registered"
restclient "k8s.io/kubernetes/pkg/client/restclient"
)
type AuthorizationInterface interface {
GetRESTClient() *restclient.RESTClient
SubjectAccessReviewsGetter
}
// AuthorizationClient is used to interact with features provided by the Authorization group.
type AuthorizationClient struct {
*restclient.RESTClient
}
func (c *AuthorizationClient) SubjectAccessReviews() SubjectAccessReviewInterface {
return newSubjectAccessReviews(c)
}
// NewForConfig creates a new AuthorizationClient for the given config.
func NewForConfig(c *restclient.Config) (*AuthorizationClient, error) {
config := *c
if err := setConfigDefaults(&config); err != nil {
return nil, err
}
client, err := restclient.RESTClientFor(&config)
if err != nil {
return nil, err
}
return &AuthorizationClient{client}, nil
}
// NewForConfigOrDie creates a new AuthorizationClient for the given config and
// panics if there is an error in the config.
func NewForConfigOrDie(c *restclient.Config) *AuthorizationClient {
client, err := NewForConfig(c)
if err != nil {
panic(err)
}
return client
}
// New creates a new AuthorizationClient for the given RESTClient.
func New(c *restclient.RESTClient) *AuthorizationClient {
return &AuthorizationClient{c}
}
func setConfigDefaults(config *restclient.Config) error {
// if authorization group is not registered, return an error
g, err := registered.Group("authorization.k8s.io")
if err != nil {
return err
}
config.APIPath = "/apis"
if config.UserAgent == "" {
config.UserAgent = restclient.DefaultKubernetesUserAgent()
}
// TODO: Unconditionally set the config.Version, until we fix the config.
//if config.Version == "" {
copyGroupVersion := g.GroupVersion
config.GroupVersion = &copyGroupVersion
//}
config.NegotiatedSerializer = api.Codecs
if config.QPS == 0 {
config.QPS = 5
}
if config.Burst == 0 {
config.Burst = 10
}
return nil
}
// GetRESTClient returns a RESTClient that is used to communicate
// with API server by this client implementation.
func (c *AuthorizationClient) GetRESTClient() *restclient.RESTClient {
if c == nil {
return nil
}
return c.RESTClient
}

View file

@ -0,0 +1,20 @@
/*
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.
*/
// This package is generated by client-gen with the default arguments.
// This package has the automatically generated typed clients.
package unversioned

View file

@ -0,0 +1,36 @@
/*
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 unversioned
import (
authorizationapi "k8s.io/kubernetes/pkg/apis/authorization"
)
// The PodExpansion interface allows manually adding extra methods to the PodInterface.
type SubjectAccessReviewExpansion interface {
Create(sar *authorizationapi.SubjectAccessReview) (result *authorizationapi.SubjectAccessReview, err error)
}
func (c *subjectAccessReviews) Create(sar *authorizationapi.SubjectAccessReview) (result *authorizationapi.SubjectAccessReview, err error) {
result = &authorizationapi.SubjectAccessReview{}
err = c.client.Post().
Resource("subjectaccessreviews").
Body(sar).
Do().
Into(result)
return
}

View file

@ -0,0 +1,40 @@
/*
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 unversioned
// SubjectAccessReviewsGetter has a method to return a SubjectAccessReviewInterface.
// A group's client should implement this interface.
type SubjectAccessReviewsGetter interface {
SubjectAccessReviews() SubjectAccessReviewInterface
}
// SubjectAccessReviewInterface has methods to work with SubjectAccessReview resources.
type SubjectAccessReviewInterface interface {
SubjectAccessReviewExpansion
}
// subjectAccessReviews implements SubjectAccessReviewInterface
type subjectAccessReviews struct {
client *AuthorizationClient
}
// newSubjectAccessReviews returns a SubjectAccessReviews
func newSubjectAccessReviews(c *AuthorizationClient) *subjectAccessReviews {
return &subjectAccessReviews{
client: c,
}
}

View file

@ -38,7 +38,7 @@ type HorizontalPodAutoscalerInterface interface {
Get(name string) (*autoscaling.HorizontalPodAutoscaler, error)
List(opts api.ListOptions) (*autoscaling.HorizontalPodAutoscalerList, error)
Watch(opts api.ListOptions) (watch.Interface, error)
Patch(name string, pt api.PatchType, data []byte) (result *autoscaling.HorizontalPodAutoscaler, err error)
Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *autoscaling.HorizontalPodAutoscaler, err error)
HorizontalPodAutoscalerExpansion
}
@ -151,11 +151,12 @@ func (c *horizontalPodAutoscalers) Watch(opts api.ListOptions) (watch.Interface,
}
// Patch applies the patch and returns the patched horizontalPodAutoscaler.
func (c *horizontalPodAutoscalers) Patch(name string, pt api.PatchType, data []byte) (result *autoscaling.HorizontalPodAutoscaler, err error) {
func (c *horizontalPodAutoscalers) Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *autoscaling.HorizontalPodAutoscaler, err error) {
result = &autoscaling.HorizontalPodAutoscaler{}
err = c.client.Patch(pt).
Namespace(c.ns).
Resource("horizontalpodautoscalers").
SubResource(subresources...).
Name(name).
Body(data).
Do().

View file

@ -38,7 +38,7 @@ type JobInterface interface {
Get(name string) (*batch.Job, error)
List(opts api.ListOptions) (*batch.JobList, error)
Watch(opts api.ListOptions) (watch.Interface, error)
Patch(name string, pt api.PatchType, data []byte) (result *batch.Job, err error)
Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *batch.Job, err error)
JobExpansion
}
@ -151,11 +151,12 @@ func (c *jobs) Watch(opts api.ListOptions) (watch.Interface, error) {
}
// Patch applies the patch and returns the patched job.
func (c *jobs) Patch(name string, pt api.PatchType, data []byte) (result *batch.Job, err error) {
func (c *jobs) Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *batch.Job, err error) {
result = &batch.Job{}
err = c.client.Patch(pt).
Namespace(c.ns).
Resource("jobs").
SubResource(subresources...).
Name(name).
Body(data).
Do().

View file

@ -38,7 +38,7 @@ type ScheduledJobInterface interface {
Get(name string) (*batch.ScheduledJob, error)
List(opts api.ListOptions) (*batch.ScheduledJobList, error)
Watch(opts api.ListOptions) (watch.Interface, error)
Patch(name string, pt api.PatchType, data []byte) (result *batch.ScheduledJob, err error)
Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *batch.ScheduledJob, err error)
ScheduledJobExpansion
}
@ -151,11 +151,12 @@ func (c *scheduledJobs) Watch(opts api.ListOptions) (watch.Interface, error) {
}
// Patch applies the patch and returns the patched scheduledJob.
func (c *scheduledJobs) Patch(name string, pt api.PatchType, data []byte) (result *batch.ScheduledJob, err error) {
func (c *scheduledJobs) Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *batch.ScheduledJob, err error) {
result = &batch.ScheduledJob{}
err = c.client.Patch(pt).
Namespace(c.ns).
Resource("scheduledjobs").
SubResource(subresources...).
Name(name).
Body(data).
Do().

View file

@ -38,7 +38,7 @@ type CertificateSigningRequestInterface interface {
Get(name string) (*certificates.CertificateSigningRequest, error)
List(opts api.ListOptions) (*certificates.CertificateSigningRequestList, error)
Watch(opts api.ListOptions) (watch.Interface, error)
Patch(name string, pt api.PatchType, data []byte) (result *certificates.CertificateSigningRequest, err error)
Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *certificates.CertificateSigningRequest, err error)
CertificateSigningRequestExpansion
}
@ -141,10 +141,11 @@ func (c *certificateSigningRequests) Watch(opts api.ListOptions) (watch.Interfac
}
// Patch applies the patch and returns the patched certificateSigningRequest.
func (c *certificateSigningRequests) Patch(name string, pt api.PatchType, data []byte) (result *certificates.CertificateSigningRequest, err error) {
func (c *certificateSigningRequests) Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *certificates.CertificateSigningRequest, err error) {
result = &certificates.CertificateSigningRequest{}
err = c.client.Patch(pt).
Resource("certificatesigningrequests").
SubResource(subresources...).
Name(name).
Body(data).
Do().

View file

@ -0,0 +1,35 @@
/*
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 unversioned
import "k8s.io/kubernetes/pkg/apis/certificates"
type CertificateSigningRequestExpansion interface {
UpdateApproval(certificateSigningRequest *certificates.CertificateSigningRequest) (result *certificates.CertificateSigningRequest, err error)
}
func (c *certificateSigningRequests) UpdateApproval(certificateSigningRequest *certificates.CertificateSigningRequest) (result *certificates.CertificateSigningRequest, err error) {
result = &certificates.CertificateSigningRequest{}
err = c.client.Put().
Resource("certificatesigningrequests").
Name(certificateSigningRequest.Name).
Body(certificateSigningRequest).
SubResource("approval").
Do().
Into(result)
return
}

View file

@ -15,5 +15,3 @@ limitations under the License.
*/
package unversioned
type CertificateSigningRequestExpansion interface{}

View file

@ -36,7 +36,7 @@ type ComponentStatusInterface interface {
Get(name string) (*api.ComponentStatus, error)
List(opts api.ListOptions) (*api.ComponentStatusList, error)
Watch(opts api.ListOptions) (watch.Interface, error)
Patch(name string, pt api.PatchType, data []byte) (result *api.ComponentStatus, err error)
Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *api.ComponentStatus, err error)
ComponentStatusExpansion
}
@ -127,10 +127,11 @@ func (c *componentStatuses) Watch(opts api.ListOptions) (watch.Interface, error)
}
// Patch applies the patch and returns the patched componentStatus.
func (c *componentStatuses) Patch(name string, pt api.PatchType, data []byte) (result *api.ComponentStatus, err error) {
func (c *componentStatuses) Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *api.ComponentStatus, err error) {
result = &api.ComponentStatus{}
err = c.client.Patch(pt).
Resource("componentstatuses").
SubResource(subresources...).
Name(name).
Body(data).
Do().

View file

@ -36,7 +36,7 @@ type ConfigMapInterface interface {
Get(name string) (*api.ConfigMap, error)
List(opts api.ListOptions) (*api.ConfigMapList, error)
Watch(opts api.ListOptions) (watch.Interface, error)
Patch(name string, pt api.PatchType, data []byte) (result *api.ConfigMap, err error)
Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *api.ConfigMap, err error)
ConfigMapExpansion
}
@ -136,11 +136,12 @@ func (c *configMaps) Watch(opts api.ListOptions) (watch.Interface, error) {
}
// Patch applies the patch and returns the patched configMap.
func (c *configMaps) Patch(name string, pt api.PatchType, data []byte) (result *api.ConfigMap, err error) {
func (c *configMaps) Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *api.ConfigMap, err error) {
result = &api.ConfigMap{}
err = c.client.Patch(pt).
Namespace(c.ns).
Resource("configmaps").
SubResource(subresources...).
Name(name).
Body(data).
Do().

View file

@ -36,7 +36,7 @@ type EndpointsInterface interface {
Get(name string) (*api.Endpoints, error)
List(opts api.ListOptions) (*api.EndpointsList, error)
Watch(opts api.ListOptions) (watch.Interface, error)
Patch(name string, pt api.PatchType, data []byte) (result *api.Endpoints, err error)
Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *api.Endpoints, err error)
EndpointsExpansion
}
@ -136,11 +136,12 @@ func (c *endpoints) Watch(opts api.ListOptions) (watch.Interface, error) {
}
// Patch applies the patch and returns the patched endpoints.
func (c *endpoints) Patch(name string, pt api.PatchType, data []byte) (result *api.Endpoints, err error) {
func (c *endpoints) Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *api.Endpoints, err error) {
result = &api.Endpoints{}
err = c.client.Patch(pt).
Namespace(c.ns).
Resource("endpoints").
SubResource(subresources...).
Name(name).
Body(data).
Do().

View file

@ -36,7 +36,7 @@ type EventInterface interface {
Get(name string) (*api.Event, error)
List(opts api.ListOptions) (*api.EventList, error)
Watch(opts api.ListOptions) (watch.Interface, error)
Patch(name string, pt api.PatchType, data []byte) (result *api.Event, err error)
Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *api.Event, err error)
EventExpansion
}
@ -136,11 +136,12 @@ func (c *events) Watch(opts api.ListOptions) (watch.Interface, error) {
}
// Patch applies the patch and returns the patched event.
func (c *events) Patch(name string, pt api.PatchType, data []byte) (result *api.Event, err error) {
func (c *events) Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *api.Event, err error) {
result = &api.Event{}
err = c.client.Patch(pt).
Namespace(c.ns).
Resource("events").
SubResource(subresources...).
Name(name).
Body(data).
Do().

View file

@ -36,7 +36,7 @@ type LimitRangeInterface interface {
Get(name string) (*api.LimitRange, error)
List(opts api.ListOptions) (*api.LimitRangeList, error)
Watch(opts api.ListOptions) (watch.Interface, error)
Patch(name string, pt api.PatchType, data []byte) (result *api.LimitRange, err error)
Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *api.LimitRange, err error)
LimitRangeExpansion
}
@ -136,11 +136,12 @@ func (c *limitRanges) Watch(opts api.ListOptions) (watch.Interface, error) {
}
// Patch applies the patch and returns the patched limitRange.
func (c *limitRanges) Patch(name string, pt api.PatchType, data []byte) (result *api.LimitRange, err error) {
func (c *limitRanges) Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *api.LimitRange, err error) {
result = &api.LimitRange{}
err = c.client.Patch(pt).
Namespace(c.ns).
Resource("limitranges").
SubResource(subresources...).
Name(name).
Body(data).
Do().

View file

@ -37,7 +37,7 @@ type NamespaceInterface interface {
Get(name string) (*api.Namespace, error)
List(opts api.ListOptions) (*api.NamespaceList, error)
Watch(opts api.ListOptions) (watch.Interface, error)
Patch(name string, pt api.PatchType, data []byte) (result *api.Namespace, err error)
Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *api.Namespace, err error)
NamespaceExpansion
}
@ -140,10 +140,11 @@ func (c *namespaces) Watch(opts api.ListOptions) (watch.Interface, error) {
}
// Patch applies the patch and returns the patched namespace.
func (c *namespaces) Patch(name string, pt api.PatchType, data []byte) (result *api.Namespace, err error) {
func (c *namespaces) Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *api.Namespace, err error) {
result = &api.Namespace{}
err = c.client.Patch(pt).
Resource("namespaces").
SubResource(subresources...).
Name(name).
Body(data).
Do().

View file

@ -37,7 +37,7 @@ type NodeInterface interface {
Get(name string) (*api.Node, error)
List(opts api.ListOptions) (*api.NodeList, error)
Watch(opts api.ListOptions) (watch.Interface, error)
Patch(name string, pt api.PatchType, data []byte) (result *api.Node, err error)
Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *api.Node, err error)
NodeExpansion
}
@ -140,10 +140,11 @@ func (c *nodes) Watch(opts api.ListOptions) (watch.Interface, error) {
}
// Patch applies the patch and returns the patched node.
func (c *nodes) Patch(name string, pt api.PatchType, data []byte) (result *api.Node, err error) {
func (c *nodes) Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *api.Node, err error) {
result = &api.Node{}
err = c.client.Patch(pt).
Resource("nodes").
SubResource(subresources...).
Name(name).
Body(data).
Do().

View file

@ -37,7 +37,7 @@ type PersistentVolumeInterface interface {
Get(name string) (*api.PersistentVolume, error)
List(opts api.ListOptions) (*api.PersistentVolumeList, error)
Watch(opts api.ListOptions) (watch.Interface, error)
Patch(name string, pt api.PatchType, data []byte) (result *api.PersistentVolume, err error)
Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *api.PersistentVolume, err error)
PersistentVolumeExpansion
}
@ -140,10 +140,11 @@ func (c *persistentVolumes) Watch(opts api.ListOptions) (watch.Interface, error)
}
// Patch applies the patch and returns the patched persistentVolume.
func (c *persistentVolumes) Patch(name string, pt api.PatchType, data []byte) (result *api.PersistentVolume, err error) {
func (c *persistentVolumes) Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *api.PersistentVolume, err error) {
result = &api.PersistentVolume{}
err = c.client.Patch(pt).
Resource("persistentvolumes").
SubResource(subresources...).
Name(name).
Body(data).
Do().

View file

@ -37,7 +37,7 @@ type PersistentVolumeClaimInterface interface {
Get(name string) (*api.PersistentVolumeClaim, error)
List(opts api.ListOptions) (*api.PersistentVolumeClaimList, error)
Watch(opts api.ListOptions) (watch.Interface, error)
Patch(name string, pt api.PatchType, data []byte) (result *api.PersistentVolumeClaim, err error)
Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *api.PersistentVolumeClaim, err error)
PersistentVolumeClaimExpansion
}
@ -150,11 +150,12 @@ func (c *persistentVolumeClaims) Watch(opts api.ListOptions) (watch.Interface, e
}
// Patch applies the patch and returns the patched persistentVolumeClaim.
func (c *persistentVolumeClaims) Patch(name string, pt api.PatchType, data []byte) (result *api.PersistentVolumeClaim, err error) {
func (c *persistentVolumeClaims) Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *api.PersistentVolumeClaim, err error) {
result = &api.PersistentVolumeClaim{}
err = c.client.Patch(pt).
Namespace(c.ns).
Resource("persistentvolumeclaims").
SubResource(subresources...).
Name(name).
Body(data).
Do().

View file

@ -37,7 +37,7 @@ type PodInterface interface {
Get(name string) (*api.Pod, error)
List(opts api.ListOptions) (*api.PodList, error)
Watch(opts api.ListOptions) (watch.Interface, error)
Patch(name string, pt api.PatchType, data []byte) (result *api.Pod, err error)
Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *api.Pod, err error)
PodExpansion
}
@ -150,11 +150,12 @@ func (c *pods) Watch(opts api.ListOptions) (watch.Interface, error) {
}
// Patch applies the patch and returns the patched pod.
func (c *pods) Patch(name string, pt api.PatchType, data []byte) (result *api.Pod, err error) {
func (c *pods) Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *api.Pod, err error) {
result = &api.Pod{}
err = c.client.Patch(pt).
Namespace(c.ns).
Resource("pods").
SubResource(subresources...).
Name(name).
Body(data).
Do().

View file

@ -36,7 +36,7 @@ type PodTemplateInterface interface {
Get(name string) (*api.PodTemplate, error)
List(opts api.ListOptions) (*api.PodTemplateList, error)
Watch(opts api.ListOptions) (watch.Interface, error)
Patch(name string, pt api.PatchType, data []byte) (result *api.PodTemplate, err error)
Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *api.PodTemplate, err error)
PodTemplateExpansion
}
@ -136,11 +136,12 @@ func (c *podTemplates) Watch(opts api.ListOptions) (watch.Interface, error) {
}
// Patch applies the patch and returns the patched podTemplate.
func (c *podTemplates) Patch(name string, pt api.PatchType, data []byte) (result *api.PodTemplate, err error) {
func (c *podTemplates) Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *api.PodTemplate, err error) {
result = &api.PodTemplate{}
err = c.client.Patch(pt).
Namespace(c.ns).
Resource("podtemplates").
SubResource(subresources...).
Name(name).
Body(data).
Do().

View file

@ -37,7 +37,7 @@ type ReplicationControllerInterface interface {
Get(name string) (*api.ReplicationController, error)
List(opts api.ListOptions) (*api.ReplicationControllerList, error)
Watch(opts api.ListOptions) (watch.Interface, error)
Patch(name string, pt api.PatchType, data []byte) (result *api.ReplicationController, err error)
Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *api.ReplicationController, err error)
ReplicationControllerExpansion
}
@ -150,11 +150,12 @@ func (c *replicationControllers) Watch(opts api.ListOptions) (watch.Interface, e
}
// Patch applies the patch and returns the patched replicationController.
func (c *replicationControllers) Patch(name string, pt api.PatchType, data []byte) (result *api.ReplicationController, err error) {
func (c *replicationControllers) Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *api.ReplicationController, err error) {
result = &api.ReplicationController{}
err = c.client.Patch(pt).
Namespace(c.ns).
Resource("replicationcontrollers").
SubResource(subresources...).
Name(name).
Body(data).
Do().

View file

@ -37,7 +37,7 @@ type ResourceQuotaInterface interface {
Get(name string) (*api.ResourceQuota, error)
List(opts api.ListOptions) (*api.ResourceQuotaList, error)
Watch(opts api.ListOptions) (watch.Interface, error)
Patch(name string, pt api.PatchType, data []byte) (result *api.ResourceQuota, err error)
Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *api.ResourceQuota, err error)
ResourceQuotaExpansion
}
@ -150,11 +150,12 @@ func (c *resourceQuotas) Watch(opts api.ListOptions) (watch.Interface, error) {
}
// Patch applies the patch and returns the patched resourceQuota.
func (c *resourceQuotas) Patch(name string, pt api.PatchType, data []byte) (result *api.ResourceQuota, err error) {
func (c *resourceQuotas) Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *api.ResourceQuota, err error) {
result = &api.ResourceQuota{}
err = c.client.Patch(pt).
Namespace(c.ns).
Resource("resourcequotas").
SubResource(subresources...).
Name(name).
Body(data).
Do().

View file

@ -36,7 +36,7 @@ type SecretInterface interface {
Get(name string) (*api.Secret, error)
List(opts api.ListOptions) (*api.SecretList, error)
Watch(opts api.ListOptions) (watch.Interface, error)
Patch(name string, pt api.PatchType, data []byte) (result *api.Secret, err error)
Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *api.Secret, err error)
SecretExpansion
}
@ -136,11 +136,12 @@ func (c *secrets) Watch(opts api.ListOptions) (watch.Interface, error) {
}
// Patch applies the patch and returns the patched secret.
func (c *secrets) Patch(name string, pt api.PatchType, data []byte) (result *api.Secret, err error) {
func (c *secrets) Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *api.Secret, err error) {
result = &api.Secret{}
err = c.client.Patch(pt).
Namespace(c.ns).
Resource("secrets").
SubResource(subresources...).
Name(name).
Body(data).
Do().

View file

@ -37,7 +37,7 @@ type ServiceInterface interface {
Get(name string) (*api.Service, error)
List(opts api.ListOptions) (*api.ServiceList, error)
Watch(opts api.ListOptions) (watch.Interface, error)
Patch(name string, pt api.PatchType, data []byte) (result *api.Service, err error)
Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *api.Service, err error)
ServiceExpansion
}
@ -150,11 +150,12 @@ func (c *services) Watch(opts api.ListOptions) (watch.Interface, error) {
}
// Patch applies the patch and returns the patched service.
func (c *services) Patch(name string, pt api.PatchType, data []byte) (result *api.Service, err error) {
func (c *services) Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *api.Service, err error) {
result = &api.Service{}
err = c.client.Patch(pt).
Namespace(c.ns).
Resource("services").
SubResource(subresources...).
Name(name).
Body(data).
Do().

View file

@ -36,7 +36,7 @@ type ServiceAccountInterface interface {
Get(name string) (*api.ServiceAccount, error)
List(opts api.ListOptions) (*api.ServiceAccountList, error)
Watch(opts api.ListOptions) (watch.Interface, error)
Patch(name string, pt api.PatchType, data []byte) (result *api.ServiceAccount, err error)
Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *api.ServiceAccount, err error)
ServiceAccountExpansion
}
@ -136,11 +136,12 @@ func (c *serviceAccounts) Watch(opts api.ListOptions) (watch.Interface, error) {
}
// Patch applies the patch and returns the patched serviceAccount.
func (c *serviceAccounts) Patch(name string, pt api.PatchType, data []byte) (result *api.ServiceAccount, err error) {
func (c *serviceAccounts) Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *api.ServiceAccount, err error) {
result = &api.ServiceAccount{}
err = c.client.Patch(pt).
Namespace(c.ns).
Resource("serviceaccounts").
SubResource(subresources...).
Name(name).
Body(data).
Do().

View file

@ -38,7 +38,7 @@ type DaemonSetInterface interface {
Get(name string) (*extensions.DaemonSet, error)
List(opts api.ListOptions) (*extensions.DaemonSetList, error)
Watch(opts api.ListOptions) (watch.Interface, error)
Patch(name string, pt api.PatchType, data []byte) (result *extensions.DaemonSet, err error)
Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *extensions.DaemonSet, err error)
DaemonSetExpansion
}
@ -151,11 +151,12 @@ func (c *daemonSets) Watch(opts api.ListOptions) (watch.Interface, error) {
}
// Patch applies the patch and returns the patched daemonSet.
func (c *daemonSets) Patch(name string, pt api.PatchType, data []byte) (result *extensions.DaemonSet, err error) {
func (c *daemonSets) Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *extensions.DaemonSet, err error) {
result = &extensions.DaemonSet{}
err = c.client.Patch(pt).
Namespace(c.ns).
Resource("daemonsets").
SubResource(subresources...).
Name(name).
Body(data).
Do().

View file

@ -38,7 +38,7 @@ type DeploymentInterface interface {
Get(name string) (*extensions.Deployment, error)
List(opts api.ListOptions) (*extensions.DeploymentList, error)
Watch(opts api.ListOptions) (watch.Interface, error)
Patch(name string, pt api.PatchType, data []byte) (result *extensions.Deployment, err error)
Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *extensions.Deployment, err error)
DeploymentExpansion
}
@ -151,11 +151,12 @@ func (c *deployments) Watch(opts api.ListOptions) (watch.Interface, error) {
}
// Patch applies the patch and returns the patched deployment.
func (c *deployments) Patch(name string, pt api.PatchType, data []byte) (result *extensions.Deployment, err error) {
func (c *deployments) Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *extensions.Deployment, err error) {
result = &extensions.Deployment{}
err = c.client.Patch(pt).
Namespace(c.ns).
Resource("deployments").
SubResource(subresources...).
Name(name).
Body(data).
Do().

View file

@ -30,6 +30,7 @@ type ExtensionsInterface interface {
PodSecurityPoliciesGetter
ReplicaSetsGetter
ScalesGetter
StorageClassesGetter
ThirdPartyResourcesGetter
}
@ -62,6 +63,10 @@ func (c *ExtensionsClient) Scales(namespace string) ScaleInterface {
return newScales(c, namespace)
}
func (c *ExtensionsClient) StorageClasses() StorageClassInterface {
return newStorageClasses(c)
}
func (c *ExtensionsClient) ThirdPartyResources() ThirdPartyResourceInterface {
return newThirdPartyResources(c)
}

View file

@ -29,3 +29,5 @@ type PodSecurityPolicyExpansion interface{}
type ThirdPartyResourceExpansion interface{}
type ReplicaSetExpansion interface{}
type StorageClassExpansion interface{}

View file

@ -38,7 +38,7 @@ type IngressInterface interface {
Get(name string) (*extensions.Ingress, error)
List(opts api.ListOptions) (*extensions.IngressList, error)
Watch(opts api.ListOptions) (watch.Interface, error)
Patch(name string, pt api.PatchType, data []byte) (result *extensions.Ingress, err error)
Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *extensions.Ingress, err error)
IngressExpansion
}
@ -151,11 +151,12 @@ func (c *ingresses) Watch(opts api.ListOptions) (watch.Interface, error) {
}
// Patch applies the patch and returns the patched ingress.
func (c *ingresses) Patch(name string, pt api.PatchType, data []byte) (result *extensions.Ingress, err error) {
func (c *ingresses) Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *extensions.Ingress, err error) {
result = &extensions.Ingress{}
err = c.client.Patch(pt).
Namespace(c.ns).
Resource("ingresses").
SubResource(subresources...).
Name(name).
Body(data).
Do().

View file

@ -37,7 +37,7 @@ type PodSecurityPolicyInterface interface {
Get(name string) (*extensions.PodSecurityPolicy, error)
List(opts api.ListOptions) (*extensions.PodSecurityPolicyList, error)
Watch(opts api.ListOptions) (watch.Interface, error)
Patch(name string, pt api.PatchType, data []byte) (result *extensions.PodSecurityPolicy, err error)
Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *extensions.PodSecurityPolicy, err error)
PodSecurityPolicyExpansion
}
@ -128,10 +128,11 @@ func (c *podSecurityPolicies) Watch(opts api.ListOptions) (watch.Interface, erro
}
// Patch applies the patch and returns the patched podSecurityPolicy.
func (c *podSecurityPolicies) Patch(name string, pt api.PatchType, data []byte) (result *extensions.PodSecurityPolicy, err error) {
func (c *podSecurityPolicies) Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *extensions.PodSecurityPolicy, err error) {
result = &extensions.PodSecurityPolicy{}
err = c.client.Patch(pt).
Resource("podsecuritypolicies").
SubResource(subresources...).
Name(name).
Body(data).
Do().

View file

@ -38,7 +38,7 @@ type ReplicaSetInterface interface {
Get(name string) (*extensions.ReplicaSet, error)
List(opts api.ListOptions) (*extensions.ReplicaSetList, error)
Watch(opts api.ListOptions) (watch.Interface, error)
Patch(name string, pt api.PatchType, data []byte) (result *extensions.ReplicaSet, err error)
Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *extensions.ReplicaSet, err error)
ReplicaSetExpansion
}
@ -151,11 +151,12 @@ func (c *replicaSets) Watch(opts api.ListOptions) (watch.Interface, error) {
}
// Patch applies the patch and returns the patched replicaSet.
func (c *replicaSets) Patch(name string, pt api.PatchType, data []byte) (result *extensions.ReplicaSet, err error) {
func (c *replicaSets) Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *extensions.ReplicaSet, err error) {
result = &extensions.ReplicaSet{}
err = c.client.Patch(pt).
Namespace(c.ns).
Resource("replicasets").
SubResource(subresources...).
Name(name).
Body(data).
Do().

View file

@ -0,0 +1,141 @@
/*
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 unversioned
import (
api "k8s.io/kubernetes/pkg/api"
extensions "k8s.io/kubernetes/pkg/apis/extensions"
watch "k8s.io/kubernetes/pkg/watch"
)
// StorageClassesGetter has a method to return a StorageClassInterface.
// A group's client should implement this interface.
type StorageClassesGetter interface {
StorageClasses() StorageClassInterface
}
// StorageClassInterface has methods to work with StorageClass resources.
type StorageClassInterface interface {
Create(*extensions.StorageClass) (*extensions.StorageClass, error)
Update(*extensions.StorageClass) (*extensions.StorageClass, error)
Delete(name string, options *api.DeleteOptions) error
DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error
Get(name string) (*extensions.StorageClass, error)
List(opts api.ListOptions) (*extensions.StorageClassList, error)
Watch(opts api.ListOptions) (watch.Interface, error)
Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *extensions.StorageClass, err error)
StorageClassExpansion
}
// storageClasses implements StorageClassInterface
type storageClasses struct {
client *ExtensionsClient
}
// newStorageClasses returns a StorageClasses
func newStorageClasses(c *ExtensionsClient) *storageClasses {
return &storageClasses{
client: c,
}
}
// Create takes the representation of a storageClass and creates it. Returns the server's representation of the storageClass, and an error, if there is any.
func (c *storageClasses) Create(storageClass *extensions.StorageClass) (result *extensions.StorageClass, err error) {
result = &extensions.StorageClass{}
err = c.client.Post().
Resource("storageclasses").
Body(storageClass).
Do().
Into(result)
return
}
// Update takes the representation of a storageClass and updates it. Returns the server's representation of the storageClass, and an error, if there is any.
func (c *storageClasses) Update(storageClass *extensions.StorageClass) (result *extensions.StorageClass, err error) {
result = &extensions.StorageClass{}
err = c.client.Put().
Resource("storageclasses").
Name(storageClass.Name).
Body(storageClass).
Do().
Into(result)
return
}
// Delete takes name of the storageClass and deletes it. Returns an error if one occurs.
func (c *storageClasses) Delete(name string, options *api.DeleteOptions) error {
return c.client.Delete().
Resource("storageclasses").
Name(name).
Body(options).
Do().
Error()
}
// DeleteCollection deletes a collection of objects.
func (c *storageClasses) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
return c.client.Delete().
Resource("storageclasses").
VersionedParams(&listOptions, api.ParameterCodec).
Body(options).
Do().
Error()
}
// Get takes name of the storageClass, and returns the corresponding storageClass object, and an error if there is any.
func (c *storageClasses) Get(name string) (result *extensions.StorageClass, err error) {
result = &extensions.StorageClass{}
err = c.client.Get().
Resource("storageclasses").
Name(name).
Do().
Into(result)
return
}
// List takes label and field selectors, and returns the list of StorageClasses that match those selectors.
func (c *storageClasses) List(opts api.ListOptions) (result *extensions.StorageClassList, err error) {
result = &extensions.StorageClassList{}
err = c.client.Get().
Resource("storageclasses").
VersionedParams(&opts, api.ParameterCodec).
Do().
Into(result)
return
}
// Watch returns a watch.Interface that watches the requested storageClasses.
func (c *storageClasses) Watch(opts api.ListOptions) (watch.Interface, error) {
return c.client.Get().
Prefix("watch").
Resource("storageclasses").
VersionedParams(&opts, api.ParameterCodec).
Watch()
}
// Patch applies the patch and returns the patched storageClass.
func (c *storageClasses) Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *extensions.StorageClass, err error) {
result = &extensions.StorageClass{}
err = c.client.Patch(pt).
Resource("storageclasses").
SubResource(subresources...).
Name(name).
Body(data).
Do().
Into(result)
return
}

View file

@ -37,7 +37,7 @@ type ThirdPartyResourceInterface interface {
Get(name string) (*extensions.ThirdPartyResource, error)
List(opts api.ListOptions) (*extensions.ThirdPartyResourceList, error)
Watch(opts api.ListOptions) (watch.Interface, error)
Patch(name string, pt api.PatchType, data []byte) (result *extensions.ThirdPartyResource, err error)
Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *extensions.ThirdPartyResource, err error)
ThirdPartyResourceExpansion
}
@ -128,10 +128,11 @@ func (c *thirdPartyResources) Watch(opts api.ListOptions) (watch.Interface, erro
}
// Patch applies the patch and returns the patched thirdPartyResource.
func (c *thirdPartyResources) Patch(name string, pt api.PatchType, data []byte) (result *extensions.ThirdPartyResource, err error) {
func (c *thirdPartyResources) Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *extensions.ThirdPartyResource, err error) {
result = &extensions.ThirdPartyResource{}
err = c.client.Patch(pt).
Resource("thirdpartyresources").
SubResource(subresources...).
Name(name).
Body(data).
Do().

View file

@ -37,7 +37,7 @@ type ClusterRoleInterface interface {
Get(name string) (*rbac.ClusterRole, error)
List(opts api.ListOptions) (*rbac.ClusterRoleList, error)
Watch(opts api.ListOptions) (watch.Interface, error)
Patch(name string, pt api.PatchType, data []byte) (result *rbac.ClusterRole, err error)
Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *rbac.ClusterRole, err error)
ClusterRoleExpansion
}
@ -128,10 +128,11 @@ func (c *clusterRoles) Watch(opts api.ListOptions) (watch.Interface, error) {
}
// Patch applies the patch and returns the patched clusterRole.
func (c *clusterRoles) Patch(name string, pt api.PatchType, data []byte) (result *rbac.ClusterRole, err error) {
func (c *clusterRoles) Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *rbac.ClusterRole, err error) {
result = &rbac.ClusterRole{}
err = c.client.Patch(pt).
Resource("clusterroles").
SubResource(subresources...).
Name(name).
Body(data).
Do().

View file

@ -37,7 +37,7 @@ type ClusterRoleBindingInterface interface {
Get(name string) (*rbac.ClusterRoleBinding, error)
List(opts api.ListOptions) (*rbac.ClusterRoleBindingList, error)
Watch(opts api.ListOptions) (watch.Interface, error)
Patch(name string, pt api.PatchType, data []byte) (result *rbac.ClusterRoleBinding, err error)
Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *rbac.ClusterRoleBinding, err error)
ClusterRoleBindingExpansion
}
@ -128,10 +128,11 @@ func (c *clusterRoleBindings) Watch(opts api.ListOptions) (watch.Interface, erro
}
// Patch applies the patch and returns the patched clusterRoleBinding.
func (c *clusterRoleBindings) Patch(name string, pt api.PatchType, data []byte) (result *rbac.ClusterRoleBinding, err error) {
func (c *clusterRoleBindings) Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *rbac.ClusterRoleBinding, err error) {
result = &rbac.ClusterRoleBinding{}
err = c.client.Patch(pt).
Resource("clusterrolebindings").
SubResource(subresources...).
Name(name).
Body(data).
Do().

View file

@ -37,7 +37,7 @@ type RoleInterface interface {
Get(name string) (*rbac.Role, error)
List(opts api.ListOptions) (*rbac.RoleList, error)
Watch(opts api.ListOptions) (watch.Interface, error)
Patch(name string, pt api.PatchType, data []byte) (result *rbac.Role, err error)
Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *rbac.Role, err error)
RoleExpansion
}
@ -137,11 +137,12 @@ func (c *roles) Watch(opts api.ListOptions) (watch.Interface, error) {
}
// Patch applies the patch and returns the patched role.
func (c *roles) Patch(name string, pt api.PatchType, data []byte) (result *rbac.Role, err error) {
func (c *roles) Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *rbac.Role, err error) {
result = &rbac.Role{}
err = c.client.Patch(pt).
Namespace(c.ns).
Resource("roles").
SubResource(subresources...).
Name(name).
Body(data).
Do().

View file

@ -37,7 +37,7 @@ type RoleBindingInterface interface {
Get(name string) (*rbac.RoleBinding, error)
List(opts api.ListOptions) (*rbac.RoleBindingList, error)
Watch(opts api.ListOptions) (watch.Interface, error)
Patch(name string, pt api.PatchType, data []byte) (result *rbac.RoleBinding, err error)
Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *rbac.RoleBinding, err error)
RoleBindingExpansion
}
@ -137,11 +137,12 @@ func (c *roleBindings) Watch(opts api.ListOptions) (watch.Interface, error) {
}
// Patch applies the patch and returns the patched roleBinding.
func (c *roleBindings) Patch(name string, pt api.PatchType, data []byte) (result *rbac.RoleBinding, err error) {
func (c *roleBindings) Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *rbac.RoleBinding, err error) {
result = &rbac.RoleBinding{}
err = c.client.Patch(pt).
Namespace(c.ns).
Resource("rolebindings").
SubResource(subresources...).
Name(name).
Body(data).
Do().

View file

@ -14,54 +14,48 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
// Package metrics provides utilities for registering client metrics to Prometheus.
// Package metrics provides abstractions for registering which metrics
// to record.
package metrics
import (
"net/url"
"sync"
"time"
"github.com/prometheus/client_golang/prometheus"
)
const restClientSubsystem = "rest_client"
var (
// RequestLatency is a Prometheus Summary metric type partitioned by
// "verb" and "url" labels. It is used for the rest client latency metrics.
RequestLatency = prometheus.NewSummaryVec(
prometheus.SummaryOpts{
Subsystem: restClientSubsystem,
Name: "request_latency_microseconds",
Help: "Request latency in microseconds. Broken down by verb and URL",
MaxAge: time.Hour,
},
[]string{"verb", "url"},
)
RequestResult = prometheus.NewCounterVec(
prometheus.CounterOpts{
Subsystem: restClientSubsystem,
Name: "request_status_codes",
Help: "Number of http requests, partitioned by metadata",
},
[]string{"code", "method", "host"},
)
)
var registerMetrics sync.Once
// Register registers all metrics to Prometheus with
// respect to the RequestLatency.
func Register() {
// Register the metrics.
// LatencyMetric observes client latency partitioned by verb and url.
type LatencyMetric interface {
Observe(verb string, u url.URL, latency time.Duration)
}
// ResultMetric counts response codes partitioned by method and host.
type ResultMetric interface {
Increment(code string, method string, host string)
}
var (
// RequestLatency is the latency metric that rest clients will update.
RequestLatency LatencyMetric = noopLatency{}
// RequestResult is the result metric that rest clients will update.
RequestResult ResultMetric = noopResult{}
)
// Register registers metrics for the rest client to use. This can
// only be called once.
func Register(lm LatencyMetric, rm ResultMetric) {
registerMetrics.Do(func() {
prometheus.MustRegister(RequestLatency)
prometheus.MustRegister(RequestResult)
RequestLatency = lm
RequestResult = rm
})
}
// Calculates the time since the specified start in microseconds.
func SinceInMicroseconds(start time.Time) float64 {
return float64(time.Since(start).Nanoseconds() / time.Microsecond.Nanoseconds())
}
type noopLatency struct{}
func (noopLatency) Observe(string, url.URL, time.Duration) {}
type noopResult struct{}
func (noopResult) Increment(string, string, string) {}

View file

@ -26,12 +26,13 @@ import (
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/client/restclient"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/util"
"k8s.io/kubernetes/pkg/util/clock"
utilruntime "k8s.io/kubernetes/pkg/util/runtime"
"k8s.io/kubernetes/pkg/watch"
"github.com/golang/glog"
"net/http"
"github.com/golang/glog"
)
const maxTriesPerEvent = 12
@ -113,7 +114,7 @@ func (eventBroadcaster *eventBroadcasterImpl) StartRecordingToSink(sink EventSin
// The default math/rand package functions aren't thread safe, so create a
// new Rand object for each StartRecording call.
randGen := rand.New(rand.NewSource(time.Now().UnixNano()))
eventCorrelator := NewEventCorrelator(util.RealClock{})
eventCorrelator := NewEventCorrelator(clock.RealClock{})
return eventBroadcaster.StartEventWatcher(
func(event *api.Event) {
recordToSink(sink, event, eventCorrelator, randGen, eventBroadcaster.sleepDuration)
@ -242,13 +243,13 @@ func (eventBroadcaster *eventBroadcasterImpl) StartEventWatcher(eventHandler fun
// NewRecorder returns an EventRecorder that records events with the given event source.
func (eventBroadcaster *eventBroadcasterImpl) NewRecorder(source api.EventSource) EventRecorder {
return &recorderImpl{source, eventBroadcaster.Broadcaster, util.RealClock{}}
return &recorderImpl{source, eventBroadcaster.Broadcaster, clock.RealClock{}}
}
type recorderImpl struct {
source api.EventSource
*watch.Broadcaster
clock util.Clock
clock clock.Clock
}
func (recorder *recorderImpl) generateEvent(object runtime.Object, timestamp unversioned.Time, eventtype, reason, message string) {

View file

@ -27,7 +27,7 @@ import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/util"
"k8s.io/kubernetes/pkg/util/clock"
"k8s.io/kubernetes/pkg/util/sets"
"k8s.io/kubernetes/pkg/util/strategicpatch"
)
@ -116,12 +116,12 @@ type EventAggregator struct {
maxIntervalInSeconds int
// clock is used to allow for testing over a time interval
clock util.Clock
clock clock.Clock
}
// NewEventAggregator returns a new instance of an EventAggregator
func NewEventAggregator(lruCacheSize int, keyFunc EventAggregatorKeyFunc, messageFunc EventAggregatorMessageFunc,
maxEvents int, maxIntervalInSeconds int, clock util.Clock) *EventAggregator {
maxEvents int, maxIntervalInSeconds int, clock clock.Clock) *EventAggregator {
return &EventAggregator{
cache: lru.New(lruCacheSize),
keyFunc: keyFunc,
@ -207,11 +207,11 @@ type eventLog struct {
type eventLogger struct {
sync.RWMutex
cache *lru.Cache
clock util.Clock
clock clock.Clock
}
// newEventLogger observes events and counts their frequencies
func newEventLogger(lruCacheEntries int, clock util.Clock) *eventLogger {
func newEventLogger(lruCacheEntries int, clock clock.Clock) *eventLogger {
return &eventLogger{cache: lru.New(lruCacheEntries), clock: clock}
}
@ -326,7 +326,7 @@ type EventCorrelateResult struct {
// the same reason.
// * Events are incrementally counted if the exact same event is encountered multiple
// times.
func NewEventCorrelator(clock util.Clock) *EventCorrelator {
func NewEventCorrelator(clock clock.Clock) *EventCorrelator {
cacheSize := maxLruCacheEntries
return &EventCorrelator{
filterFunc: DefaultEventFilterFunc,

View file

@ -108,6 +108,10 @@ type Config struct {
// Rate limiter for limiting connections to the master from this client. If present overwrites QPS/Burst
RateLimiter flowcontrol.RateLimiter
// Version forces a specific version to be used (if registered)
// Do we need this?
// Version string
}
// TLSClientConfig contains settings to enable transport layer security
@ -131,6 +135,9 @@ type TLSClientConfig struct {
}
type ContentConfig struct {
// AcceptContentTypes specifies the types the client will accept and is optional.
// If not set, ContentType will be used to define the Accept header
AcceptContentTypes string
// ContentType specifies the wire format used to communicate with the server.
// This value will be set as the Accept header on requests made to the server, and
// as the default content type on any object sent to the server. If not set,
@ -240,7 +247,7 @@ func DefaultKubernetesUserAgent() string {
// InClusterConfig returns a config object which uses the service account
// kubernetes gives to pods. It's intended for clients that expect to be
// running inside a pod running on kuberenetes. It will return an error if
// running inside a pod running on kubernetes. It will return an error if
// called from a process not running in a kubernetes environment.
func InClusterConfig() (*Config, error) {
host, port := os.Getenv("KUBERNETES_SERVICE_HOST"), os.Getenv("KUBERNETES_SERVICE_PORT")

View file

@ -18,6 +18,7 @@ package restclient
import (
"bytes"
"encoding/hex"
"fmt"
"io"
"io/ioutil"
@ -57,10 +58,6 @@ var (
longThrottleLatency = 50 * time.Millisecond
)
func init() {
metrics.Register()
}
// HTTPClient is an interface for testing a request object.
type HTTPClient interface {
Do(req *http.Request) (*http.Response, error)
@ -143,7 +140,10 @@ func NewRequest(client HTTPClient, verb string, baseURL *url.URL, versionedAPIPa
backoffMgr: backoff,
throttle: throttle,
}
if len(content.ContentType) > 0 {
switch {
case len(content.AcceptContentTypes) > 0:
r.SetHeader("Accept", content.AcceptContentTypes)
case len(content.ContentType) > 0:
r.SetHeader("Accept", content.ContentType+", */*")
}
return r
@ -335,16 +335,16 @@ func (r resourceTypeToFieldMapping) filterField(resourceType, field, value strin
type versionToResourceToFieldMapping map[unversioned.GroupVersion]resourceTypeToFieldMapping
// filterField transforms the given field/value selector for the given groupVersion and resource
func (v versionToResourceToFieldMapping) filterField(groupVersion *unversioned.GroupVersion, resourceType, field, value string) (newField, newValue string, err error) {
rMapping, ok := v[*groupVersion]
if !ok {
glog.Warningf("Field selector: %v - %v - %v - %v: need to check if this is versioned correctly.", groupVersion, resourceType, field, value)
// no groupVersion overrides registered, default to identity mapping
return field, value, nil
}
newField, newValue, err = rMapping.filterField(resourceType, field, value)
if err != nil {
// This is only a warning until we find and fix all of the client's usages.
glog.Warningf("Field selector: %v - %v - %v - %v: need to check if this is versioned correctly.", groupVersion, resourceType, field, value)
// no groupVersionResource overrides registered, default to identity mapping
return field, value, nil
}
return newField, newValue, nil
@ -538,10 +538,10 @@ func (r *Request) Body(obj interface{}) *Request {
r.err = err
return r
}
glog.V(8).Infof("Request Body: %s", string(data))
glog.V(8).Infof("Request Body: %#v", string(data))
r.body = bytes.NewReader(data)
case []byte:
glog.V(8).Infof("Request Body: %s", string(t))
glog.V(8).Infof("Request Body: %#v", string(t))
r.body = bytes.NewReader(t)
case io.Reader:
r.body = t
@ -555,7 +555,7 @@ func (r *Request) Body(obj interface{}) *Request {
r.err = err
return r
}
glog.V(8).Infof("Request Body: %s", string(data))
glog.V(8).Infof("Request Body: %#v", string(data))
r.body = bytes.NewReader(data)
r.SetHeader("Content-Type", r.content.ContentType)
default:
@ -605,7 +605,7 @@ func (r *Request) URL() *url.URL {
// underyling object. This means some useful request info (like the types of field
// selectors in use) will be lost.
// TODO: preserve field selector keys
func (r Request) finalURLTemplate() string {
func (r Request) finalURLTemplate() url.URL {
if len(r.resourceName) != 0 {
r.resourceName = "{name}"
}
@ -618,7 +618,8 @@ func (r Request) finalURLTemplate() string {
newParams[k] = v
}
r.params = newParams
return r.URL().String()
url := r.URL()
return *url
}
func (r *Request) tryThrottle() {
@ -693,10 +694,10 @@ func updateURLMetrics(req *Request, resp *http.Response, err error) {
// If we have an error (i.e. apiserver down) we report that as a metric label.
if err != nil {
metrics.RequestResult.WithLabelValues(err.Error(), req.verb, url).Inc()
metrics.RequestResult.Increment(err.Error(), req.verb, url)
} else {
//Metrics for failure codes
metrics.RequestResult.WithLabelValues(strconv.Itoa(resp.StatusCode), req.verb, url).Inc()
metrics.RequestResult.Increment(strconv.Itoa(resp.StatusCode), req.verb, url)
}
}
@ -771,7 +772,7 @@ func (r *Request) request(fn func(*http.Request, *http.Response)) error {
//Metrics for total request latency
start := time.Now()
defer func() {
metrics.RequestLatency.WithLabelValues(r.verb, r.finalURLTemplate()).Observe(metrics.SinceInMicroseconds(start))
metrics.RequestLatency.Observe(r.verb, r.finalURLTemplate(), time.Since(start))
}()
if r.err != nil {
@ -817,9 +818,16 @@ func (r *Request) request(fn func(*http.Request, *http.Response)) error {
}
done := func() bool {
// ensure the response body is closed before we reconnect, so that we reuse the same
// TCP connection
defer resp.Body.Close()
// Ensure the response body is fully read and closed
// before we reconnect, so that we reuse the same TCP
// connection.
defer func() {
const maxBodySlurpSize = 2 << 10
if resp.ContentLength <= maxBodySlurpSize {
io.Copy(ioutil.Discard, &io.LimitedReader{R: resp.Body, N: maxBodySlurpSize})
}
resp.Body.Close()
}()
retries++
if seconds, wait := checkWait(resp); wait && retries < maxRetries {
@ -873,6 +881,9 @@ func (r *Request) DoRaw() ([]byte, error) {
var result Result
err := r.request(func(req *http.Request, resp *http.Response) {
result.body, result.err = ioutil.ReadAll(resp.Body)
if resp.StatusCode < http.StatusOK || resp.StatusCode > http.StatusPartialContent {
result.err = r.transformUnstructuredResponseError(resp, req, result.body)
}
})
if err != nil {
return nil, err
@ -888,16 +899,49 @@ func (r *Request) transformResponse(resp *http.Response, req *http.Request) Resu
body = data
}
}
glog.V(8).Infof("Response Body: %s", string(body))
if glog.V(8) {
switch {
case bytes.IndexFunc(body, func(r rune) bool { return r < 0x0a }) != -1:
glog.Infof("Response Body:\n%s", hex.Dump(body))
default:
glog.Infof("Response Body: %s", string(body))
}
}
// verify the content type is accurate
contentType := resp.Header.Get("Content-Type")
decoder := r.serializers.Decoder
if len(contentType) > 0 && (decoder == nil || (len(r.content.ContentType) > 0 && contentType != r.content.ContentType)) {
mediaType, params, err := mime.ParseMediaType(contentType)
if err != nil {
return Result{err: errors.NewInternalError(err)}
}
decoder, err = r.serializers.RenegotiatedDecoder(mediaType, params)
if err != nil {
// if we fail to negotiate a decoder, treat this as an unstructured error
switch {
case resp.StatusCode == http.StatusSwitchingProtocols:
// no-op, we've been upgraded
case resp.StatusCode < http.StatusOK || resp.StatusCode > http.StatusPartialContent:
return Result{err: r.transformUnstructuredResponseError(resp, req, body)}
}
return Result{
body: body,
contentType: contentType,
statusCode: resp.StatusCode,
}
}
}
// Did the server give us a status response?
isStatusResponse := false
status := &unversioned.Status{}
// Because release-1.1 server returns Status with empty APIVersion at paths
// to the Extensions resources, we need to use DecodeInto here to provide
// default groupVersion, otherwise a status response won't be correctly
// decoded.
status := &unversioned.Status{}
err := runtime.DecodeInto(r.serializers.Decoder, body, status)
err := runtime.DecodeInto(decoder, body, status)
if err == nil && len(status.Status) > 0 {
isStatusResponse = true
}
@ -919,25 +963,6 @@ func (r *Request) transformResponse(resp *http.Response, req *http.Request) Resu
return Result{err: errors.FromObject(status)}
}
contentType := resp.Header.Get("Content-Type")
var decoder runtime.Decoder
if contentType == r.content.ContentType {
decoder = r.serializers.Decoder
} else {
mediaType, params, err := mime.ParseMediaType(contentType)
if err != nil {
return Result{err: errors.NewInternalError(err)}
}
decoder, err = r.serializers.RenegotiatedDecoder(mediaType, params)
if err != nil {
return Result{
body: body,
contentType: contentType,
statusCode: resp.StatusCode,
}
}
}
return Result{
body: body,
contentType: contentType,
@ -970,7 +995,7 @@ func (r *Request) transformUnstructuredResponseError(resp *http.Response, req *h
body = data
}
}
glog.V(8).Infof("Response Body: %s", string(body))
glog.V(8).Infof("Response Body: %#v", string(body))
message := "unknown"
if isTextResponse(resp) {

View file

@ -234,7 +234,7 @@ func (d *DiscoveryClient) ServerVersion() (*version.Info, error) {
// SwaggerSchema retrieves and parses the swagger API schema the server supports.
func (d *DiscoveryClient) SwaggerSchema(version unversioned.GroupVersion) (*swagger.ApiDeclaration, error) {
if version.IsEmpty() {
if version.Empty() {
return nil, fmt.Errorf("groupVersion cannot be empty")
}

View file

@ -0,0 +1,263 @@
/*
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 discovery
import (
"sync"
"k8s.io/kubernetes/pkg/api/errors"
"k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/api/unversioned"
)
// APIGroupResources is an API group with a mapping of versions to
// resources.
type APIGroupResources struct {
Group unversioned.APIGroup
// A mapping of version string to a slice of APIResources for
// that version.
VersionedResources map[string][]unversioned.APIResource
}
// NewRESTMapper returns a PriorityRESTMapper based on the discovered
// groups and resourced passed in.
func NewRESTMapper(groupResources []*APIGroupResources, versionInterfaces meta.VersionInterfacesFunc) meta.RESTMapper {
unionMapper := meta.MultiRESTMapper{}
var groupPriority []string
var resourcePriority []unversioned.GroupVersionResource
var kindPriority []unversioned.GroupVersionKind
for _, group := range groupResources {
groupPriority = append(groupPriority, group.Group.Name)
if len(group.Group.PreferredVersion.Version) != 0 {
preffered := group.Group.PreferredVersion.Version
if _, ok := group.VersionedResources[preffered]; ok {
resourcePriority = append(resourcePriority, unversioned.GroupVersionResource{
Group: group.Group.Name,
Version: group.Group.PreferredVersion.Version,
Resource: meta.AnyResource,
})
kindPriority = append(kindPriority, unversioned.GroupVersionKind{
Group: group.Group.Name,
Version: group.Group.PreferredVersion.Version,
Kind: meta.AnyKind,
})
}
}
for _, discoveryVersion := range group.Group.Versions {
resources, ok := group.VersionedResources[discoveryVersion.Version]
if !ok {
continue
}
gv := unversioned.GroupVersion{Group: group.Group.Name, Version: discoveryVersion.Version}
versionMapper := meta.NewDefaultRESTMapper([]unversioned.GroupVersion{gv}, versionInterfaces)
for _, resource := range resources {
scope := meta.RESTScopeNamespace
if !resource.Namespaced {
scope = meta.RESTScopeRoot
}
versionMapper.Add(gv.WithKind(resource.Kind), scope)
// TODO only do this if it supports listing
versionMapper.Add(gv.WithKind(resource.Kind+"List"), scope)
}
// TODO why is this type not in discovery (at least for "v1")
versionMapper.Add(gv.WithKind("List"), meta.RESTScopeRoot)
unionMapper = append(unionMapper, versionMapper)
}
}
for _, group := range groupPriority {
resourcePriority = append(resourcePriority, unversioned.GroupVersionResource{
Group: group,
Version: meta.AnyVersion,
Resource: meta.AnyResource,
})
kindPriority = append(kindPriority, unversioned.GroupVersionKind{
Group: group,
Version: meta.AnyVersion,
Kind: meta.AnyKind,
})
}
return meta.PriorityRESTMapper{
Delegate: unionMapper,
ResourcePriority: resourcePriority,
KindPriority: kindPriority,
}
}
// GetAPIGroupResources uses the provided discovery client to gather
// discovery information and populate a slice of APIGroupResources.
func GetAPIGroupResources(cl DiscoveryInterface) ([]*APIGroupResources, error) {
apiGroups, err := cl.ServerGroups()
if err != nil {
return nil, err
}
var result []*APIGroupResources
for _, group := range apiGroups.Groups {
groupResources := &APIGroupResources{
Group: group,
VersionedResources: make(map[string][]unversioned.APIResource),
}
for _, version := range group.Versions {
resources, err := cl.ServerResourcesForGroupVersion(version.GroupVersion)
if err != nil {
if errors.IsNotFound(err) {
continue // ignore as this can race with deletion of 3rd party APIs
}
return nil, err
}
groupResources.VersionedResources[version.Version] = resources.APIResources
}
result = append(result, groupResources)
}
return result, nil
}
// DeferredDiscoveryRESTMapper is a RESTMapper that will defer
// initialization of the RESTMapper until the first mapping is
// requested.
type DeferredDiscoveryRESTMapper struct {
initMu sync.Mutex
delegate meta.RESTMapper
cl DiscoveryInterface
versionInterface meta.VersionInterfacesFunc
}
// NewDeferredDiscoveryRESTMapper returns a
// DeferredDiscoveryRESTMapper that will lazily query the provided
// client for discovery information to do REST mappings.
func NewDeferredDiscoveryRESTMapper(cl DiscoveryInterface, versionInterface meta.VersionInterfacesFunc) *DeferredDiscoveryRESTMapper {
return &DeferredDiscoveryRESTMapper{
cl: cl,
versionInterface: versionInterface,
}
}
func (d *DeferredDiscoveryRESTMapper) getDelegate() (meta.RESTMapper, error) {
d.initMu.Lock()
defer d.initMu.Unlock()
if d.delegate != nil {
return d.delegate, nil
}
groupResources, err := GetAPIGroupResources(d.cl)
if err != nil {
return nil, err
}
d.delegate = NewRESTMapper(groupResources, d.versionInterface)
return d.delegate, err
}
// Reset resets the internally cached Discovery information and will
// cause the next mapping request to re-discover.
func (d *DeferredDiscoveryRESTMapper) Reset() {
d.initMu.Lock()
d.delegate = nil
d.initMu.Unlock()
}
// KindFor takes a partial resource and returns back the single match.
// It returns an error if there are multiple matches.
func (d *DeferredDiscoveryRESTMapper) KindFor(resource unversioned.GroupVersionResource) (unversioned.GroupVersionKind, error) {
del, err := d.getDelegate()
if err != nil {
return unversioned.GroupVersionKind{}, err
}
return del.KindFor(resource)
}
// KindsFor takes a partial resource and returns back the list of
// potential kinds in priority order.
func (d *DeferredDiscoveryRESTMapper) KindsFor(resource unversioned.GroupVersionResource) ([]unversioned.GroupVersionKind, error) {
del, err := d.getDelegate()
if err != nil {
return nil, err
}
return del.KindsFor(resource)
}
// ResourceFor takes a partial resource and returns back the single
// match. It returns an error if there are multiple matches.
func (d *DeferredDiscoveryRESTMapper) ResourceFor(input unversioned.GroupVersionResource) (unversioned.GroupVersionResource, error) {
del, err := d.getDelegate()
if err != nil {
return unversioned.GroupVersionResource{}, err
}
return del.ResourceFor(input)
}
// ResourcesFor takes a partial resource and returns back the list of
// potential resource in priority order.
func (d *DeferredDiscoveryRESTMapper) ResourcesFor(input unversioned.GroupVersionResource) ([]unversioned.GroupVersionResource, error) {
del, err := d.getDelegate()
if err != nil {
return nil, err
}
return del.ResourcesFor(input)
}
// RESTMapping identifies a preferred resource mapping for the
// provided group kind.
func (d *DeferredDiscoveryRESTMapper) RESTMapping(gk unversioned.GroupKind, versions ...string) (*meta.RESTMapping, error) {
del, err := d.getDelegate()
if err != nil {
return nil, err
}
return del.RESTMapping(gk, versions...)
}
// RESTMappings returns the RESTMappings for the provided group kind
// in a rough internal preferred order. If no kind is found, it will
// return a NoResourceMatchError.
func (d *DeferredDiscoveryRESTMapper) RESTMappings(gk unversioned.GroupKind) ([]*meta.RESTMapping, error) {
del, err := d.getDelegate()
if err != nil {
return nil, err
}
return del.RESTMappings(gk)
}
// AliasesForResource returns whether a resource has an alias or not.
func (d *DeferredDiscoveryRESTMapper) AliasesForResource(resource string) ([]string, bool) {
del, err := d.getDelegate()
if err != nil {
return nil, false
}
return del.AliasesForResource(resource)
}
// ResourceSingularizer converts a resource name from plural to
// singular (e.g., from pods to pod).
func (d *DeferredDiscoveryRESTMapper) ResourceSingularizer(resource string) (singular string, err error) {
del, err := d.getDelegate()
if err != nil {
return resource, err
}
return del.ResourceSingularizer(resource)
}
// Make sure it satisfies the interface
var _ meta.RESTMapper = &DeferredDiscoveryRESTMapper{}

View file

@ -0,0 +1,95 @@
/*
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 discovery
import (
"fmt"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/runtime"
)
// UnstructuredObjectTyper provides a runtime.ObjectTyper implmentation for
// runtime.Unstructured object based on discovery information.
type UnstructuredObjectTyper struct {
registered map[unversioned.GroupVersionKind]bool
}
// NewUnstructuredObjectTyper returns a runtime.ObjectTyper for
// unstructred objects based on discovery information.
func NewUnstructuredObjectTyper(groupResources []*APIGroupResources) *UnstructuredObjectTyper {
dot := &UnstructuredObjectTyper{registered: make(map[unversioned.GroupVersionKind]bool)}
for _, group := range groupResources {
for _, discoveryVersion := range group.Group.Versions {
resources, ok := group.VersionedResources[discoveryVersion.Version]
if !ok {
continue
}
gv := unversioned.GroupVersion{Group: group.Group.Name, Version: discoveryVersion.Version}
for _, resource := range resources {
dot.registered[gv.WithKind(resource.Kind)] = true
}
}
}
return dot
}
// ObjectKind returns the group,version,kind of the provided object, or an error
// if the object in not *runtime.Unstructured or has no group,version,kind
// information.
func (d *UnstructuredObjectTyper) ObjectKind(obj runtime.Object) (unversioned.GroupVersionKind, error) {
if _, ok := obj.(*runtime.Unstructured); !ok {
return unversioned.GroupVersionKind{}, fmt.Errorf("type %T is invalid for dynamic object typer", obj)
}
return obj.GetObjectKind().GroupVersionKind(), nil
}
// ObjectKinds returns a slice of one element with the group,version,kind of the
// provided object, or an error if the object is not *runtime.Unstructured or
// has no group,version,kind information. unversionedType will always be false
// because runtime.Unstructured object should always have group,version,kind
// information set.
func (d *UnstructuredObjectTyper) ObjectKinds(obj runtime.Object) (gvks []unversioned.GroupVersionKind, unversionedType bool, err error) {
gvk, err := d.ObjectKind(obj)
if err != nil {
return nil, false, err
}
return []unversioned.GroupVersionKind{gvk}, false, nil
}
// Recognizes returns true if the provided group,version,kind was in the
// discovery information.
func (d *UnstructuredObjectTyper) Recognizes(gvk unversioned.GroupVersionKind) bool {
return d.registered[gvk]
}
// IsUnversioned returns false always because *runtime.Unstructured objects
// should always have group,version,kind information set. ok will be true if the
// object's group,version,kind is registered.
func (d *UnstructuredObjectTyper) IsUnversioned(obj runtime.Object) (unversioned bool, ok bool) {
gvk, err := d.ObjectKind(obj)
if err != nil {
return false, false
}
return false, d.registered[gvk]
}
var _ runtime.ObjectTyper = &UnstructuredObjectTyper{}

View file

@ -0,0 +1,289 @@
/*
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 dynamic provides a client interface to arbitrary Kubernetes
// APIs that exposes common high level operations and exposes common
// metadata.
package dynamic
import (
"encoding/json"
"errors"
"io"
"net/url"
"strings"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/client/restclient"
"k8s.io/kubernetes/pkg/conversion/queryparams"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/runtime/serializer"
"k8s.io/kubernetes/pkg/util/flowcontrol"
"k8s.io/kubernetes/pkg/watch"
)
// Client is a Kubernetes client that allows you to access metadata
// and manipulate metadata of a Kubernetes API group.
type Client struct {
cl *restclient.RESTClient
parameterCodec runtime.ParameterCodec
}
// NewClient returns a new client based on the passed in config. The
// codec is ignored, as the dynamic client uses it's own codec.
func NewClient(conf *restclient.Config) (*Client, error) {
// avoid changing the original config
confCopy := *conf
conf = &confCopy
contentConfig := ContentConfig()
contentConfig.GroupVersion = conf.GroupVersion
if conf.NegotiatedSerializer != nil {
contentConfig.NegotiatedSerializer = conf.NegotiatedSerializer
}
conf.ContentConfig = contentConfig
if conf.APIPath == "" {
conf.APIPath = "/api"
}
if len(conf.UserAgent) == 0 {
conf.UserAgent = restclient.DefaultKubernetesUserAgent()
}
cl, err := restclient.RESTClientFor(conf)
if err != nil {
return nil, err
}
return &Client{cl: cl}, nil
}
// GetRateLimiter returns rate limier.
func (c *Client) GetRateLimiter() flowcontrol.RateLimiter {
return c.cl.GetRateLimiter()
}
// Resource returns an API interface to the specified resource for this client's
// group and version. If resource is not a namespaced resource, then namespace
// is ignored. The ResourceClient inherits the parameter codec of c.
func (c *Client) Resource(resource *unversioned.APIResource, namespace string) *ResourceClient {
return &ResourceClient{
cl: c.cl,
resource: resource,
ns: namespace,
parameterCodec: c.parameterCodec,
}
}
// ParameterCodec returns a client with the provided parameter codec.
func (c *Client) ParameterCodec(parameterCodec runtime.ParameterCodec) *Client {
return &Client{
cl: c.cl,
parameterCodec: parameterCodec,
}
}
// ResourceClient is an API interface to a specific resource under a
// dynamic client.
type ResourceClient struct {
cl *restclient.RESTClient
resource *unversioned.APIResource
ns string
parameterCodec runtime.ParameterCodec
}
// List returns a list of objects for this resource.
func (rc *ResourceClient) List(opts runtime.Object) (runtime.Object, error) {
parameterEncoder := rc.parameterCodec
if parameterEncoder == nil {
parameterEncoder = defaultParameterEncoder
}
return rc.cl.Get().
NamespaceIfScoped(rc.ns, rc.resource.Namespaced).
Resource(rc.resource.Name).
VersionedParams(opts, parameterEncoder).
Do().
Get()
}
// Get gets the resource with the specified name.
func (rc *ResourceClient) Get(name string) (*runtime.Unstructured, error) {
result := new(runtime.Unstructured)
err := rc.cl.Get().
NamespaceIfScoped(rc.ns, rc.resource.Namespaced).
Resource(rc.resource.Name).
Name(name).
Do().
Into(result)
return result, err
}
// Delete deletes the resource with the specified name.
func (rc *ResourceClient) Delete(name string, opts *v1.DeleteOptions) error {
return rc.cl.Delete().
NamespaceIfScoped(rc.ns, rc.resource.Namespaced).
Resource(rc.resource.Name).
Name(name).
Body(opts).
Do().
Error()
}
// DeleteCollection deletes a collection of objects.
func (rc *ResourceClient) DeleteCollection(deleteOptions *v1.DeleteOptions, listOptions runtime.Object) error {
parameterEncoder := rc.parameterCodec
if parameterEncoder == nil {
parameterEncoder = defaultParameterEncoder
}
return rc.cl.Delete().
NamespaceIfScoped(rc.ns, rc.resource.Namespaced).
Resource(rc.resource.Name).
VersionedParams(listOptions, parameterEncoder).
Body(deleteOptions).
Do().
Error()
}
// Create creates the provided resource.
func (rc *ResourceClient) Create(obj *runtime.Unstructured) (*runtime.Unstructured, error) {
result := new(runtime.Unstructured)
err := rc.cl.Post().
NamespaceIfScoped(rc.ns, rc.resource.Namespaced).
Resource(rc.resource.Name).
Body(obj).
Do().
Into(result)
return result, err
}
// Update updates the provided resource.
func (rc *ResourceClient) Update(obj *runtime.Unstructured) (*runtime.Unstructured, error) {
result := new(runtime.Unstructured)
if len(obj.GetName()) == 0 {
return result, errors.New("object missing name")
}
err := rc.cl.Put().
NamespaceIfScoped(rc.ns, rc.resource.Namespaced).
Resource(rc.resource.Name).
Name(obj.GetName()).
Body(obj).
Do().
Into(result)
return result, err
}
// Watch returns a watch.Interface that watches the resource.
func (rc *ResourceClient) Watch(opts runtime.Object) (watch.Interface, error) {
parameterEncoder := rc.parameterCodec
if parameterEncoder == nil {
parameterEncoder = defaultParameterEncoder
}
return rc.cl.Get().
Prefix("watch").
NamespaceIfScoped(rc.ns, rc.resource.Namespaced).
Resource(rc.resource.Name).
VersionedParams(opts, parameterEncoder).
Watch()
}
func (rc *ResourceClient) Patch(name string, pt api.PatchType, data []byte) (*runtime.Unstructured, error) {
result := new(runtime.Unstructured)
err := rc.cl.Patch(pt).
NamespaceIfScoped(rc.ns, rc.resource.Namespaced).
Resource(rc.resource.Name).
Name(name).
Body(data).
Do().
Into(result)
return result, err
}
// dynamicCodec is a codec that wraps the standard unstructured codec
// with special handling for Status objects.
type dynamicCodec struct{}
func (dynamicCodec) Decode(data []byte, gvk *unversioned.GroupVersionKind, obj runtime.Object) (runtime.Object, *unversioned.GroupVersionKind, error) {
obj, gvk, err := runtime.UnstructuredJSONScheme.Decode(data, gvk, obj)
if err != nil {
return nil, nil, err
}
if _, ok := obj.(*unversioned.Status); !ok && strings.ToLower(gvk.Kind) == "status" {
obj = &unversioned.Status{}
err := json.Unmarshal(data, obj)
if err != nil {
return nil, nil, err
}
}
return obj, gvk, nil
}
func (dynamicCodec) Encode(obj runtime.Object, w io.Writer) error {
return runtime.UnstructuredJSONScheme.Encode(obj, w)
}
// ContentConfig returns a restclient.ContentConfig for dynamic types.
func ContentConfig() restclient.ContentConfig {
// TODO: it's questionable that this should be using anything other than unstructured schema and JSON
codec := dynamicCodec{}
streamingInfo, _ := api.Codecs.StreamingSerializerForMediaType("application/json;stream=watch", nil)
return restclient.ContentConfig{
AcceptContentTypes: runtime.ContentTypeJSON,
ContentType: runtime.ContentTypeJSON,
NegotiatedSerializer: serializer.NegotiatedSerializerWrapper(runtime.SerializerInfo{Serializer: codec}, streamingInfo),
}
}
// paramaterCodec is a codec converts an API object to query
// parameters without trying to convert to the target version.
type parameterCodec struct{}
func (parameterCodec) EncodeParameters(obj runtime.Object, to unversioned.GroupVersion) (url.Values, error) {
return queryparams.Convert(obj)
}
func (parameterCodec) DecodeParameters(parameters url.Values, from unversioned.GroupVersion, into runtime.Object) error {
return errors.New("DecodeParameters not implemented on dynamic parameterCodec")
}
var defaultParameterEncoder runtime.ParameterCodec = parameterCodec{}
type versionedParameterEncoderWithV1Fallback struct{}
func (versionedParameterEncoderWithV1Fallback) EncodeParameters(obj runtime.Object, to unversioned.GroupVersion) (url.Values, error) {
ret, err := api.ParameterCodec.EncodeParameters(obj, to)
if err != nil && runtime.IsNotRegisteredError(err) {
// fallback to v1
return api.ParameterCodec.EncodeParameters(obj, v1.SchemeGroupVersion)
}
return ret, err
}
func (versionedParameterEncoderWithV1Fallback) DecodeParameters(parameters url.Values, from unversioned.GroupVersion, into runtime.Object) error {
return errors.New("DecodeParameters not implemented on versionedParameterEncoderWithV1Fallback")
}
// VersionedParameterEncoderWithV1Fallback is useful for encoding query
// parameters for thirdparty resources. It tries to convert object to the
// specified version before converting it to query parameters, and falls back to
// converting to v1 if the object is not registered in the specified version.
// For the record, currently API server always treats query parameters sent to a
// thirdparty resource endpoint as v1.
var VersionedParameterEncoderWithV1Fallback runtime.ParameterCodec = versionedParameterEncoderWithV1Fallback{}

View file

@ -0,0 +1,95 @@
/*
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 dynamic
import (
"sync"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/client/restclient"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/runtime/serializer"
)
// ClientPool manages a pool of dynamic clients.
type ClientPool interface {
// ClientForGroupVersion returns a client configured for the specified groupVersion.
ClientForGroupVersion(groupVersion unversioned.GroupVersion) (*Client, error)
}
// APIPathResolverFunc knows how to convert a groupVersion to its API path.
type APIPathResolverFunc func(groupVersion unversioned.GroupVersion) string
// LegacyAPIPathResolverFunc can resolve paths properly with the legacy API.
func LegacyAPIPathResolverFunc(groupVersion unversioned.GroupVersion) string {
if len(groupVersion.Group) == 0 {
return "/api"
}
return "/apis"
}
// clientPoolImpl implements Factory
type clientPoolImpl struct {
lock sync.RWMutex
config *restclient.Config
clients map[unversioned.GroupVersion]*Client
apiPathResolverFunc APIPathResolverFunc
}
// NewClientPool returns a ClientPool from the specified config
func NewClientPool(config *restclient.Config, apiPathResolverFunc APIPathResolverFunc) ClientPool {
confCopy := *config
return &clientPoolImpl{
config: &confCopy,
clients: map[unversioned.GroupVersion]*Client{},
apiPathResolverFunc: apiPathResolverFunc,
}
}
// ClientForGroupVersion returns a client for the specified groupVersion, creates one if none exists
func (c *clientPoolImpl) ClientForGroupVersion(groupVersion unversioned.GroupVersion) (*Client, error) {
c.lock.Lock()
defer c.lock.Unlock()
// do we have a client already configured?
if existingClient, found := c.clients[groupVersion]; found {
return existingClient, nil
}
// avoid changing the original config
confCopy := *c.config
conf := &confCopy
// we need to set the api path based on group version, if no group, default to legacy path
conf.APIPath = c.apiPathResolverFunc(groupVersion)
// we need to make a client
conf.GroupVersion = &groupVersion
if conf.NegotiatedSerializer == nil {
streamingInfo, _ := api.Codecs.StreamingSerializerForMediaType("application/json;stream=watch", nil)
conf.NegotiatedSerializer = serializer.NegotiatedSerializerWrapper(runtime.SerializerInfo{Serializer: dynamicCodec{}}, streamingInfo)
}
dynamicClient, err := NewClient(conf)
if err != nil {
return nil, err
}
c.clients[groupVersion] = dynamicClient
return dynamicClient, nil
}

View file

@ -0,0 +1,94 @@
/*
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 dynamic
import (
"fmt"
"k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/runtime"
)
// VersionInterfaces provides an object converter and metadata
// accessor appropriate for use with unstructured objects.
func VersionInterfaces(unversioned.GroupVersion) (*meta.VersionInterfaces, error) {
return &meta.VersionInterfaces{
ObjectConvertor: &runtime.UnstructuredObjectConverter{},
MetadataAccessor: meta.NewAccessor(),
}, nil
}
// NewDiscoveryRESTMapper returns a RESTMapper based on discovery information.
func NewDiscoveryRESTMapper(resources []*unversioned.APIResourceList, versionFunc meta.VersionInterfacesFunc) (*meta.DefaultRESTMapper, error) {
rm := meta.NewDefaultRESTMapper(nil, versionFunc)
for _, resourceList := range resources {
gv, err := unversioned.ParseGroupVersion(resourceList.GroupVersion)
if err != nil {
return nil, err
}
for _, resource := range resourceList.APIResources {
gvk := gv.WithKind(resource.Kind)
scope := meta.RESTScopeRoot
if resource.Namespaced {
scope = meta.RESTScopeNamespace
}
rm.Add(gvk, scope)
}
}
return rm, nil
}
// ObjectTyper provides an ObjectTyper implementation for
// runtime.Unstructured object based on discovery information.
type ObjectTyper struct {
registered map[unversioned.GroupVersionKind]bool
}
// NewObjectTyper constructs an ObjectTyper from discovery information.
func NewObjectTyper(resources []*unversioned.APIResourceList) (runtime.ObjectTyper, error) {
ot := &ObjectTyper{registered: make(map[unversioned.GroupVersionKind]bool)}
for _, resourceList := range resources {
gv, err := unversioned.ParseGroupVersion(resourceList.GroupVersion)
if err != nil {
return nil, err
}
for _, resource := range resourceList.APIResources {
ot.registered[gv.WithKind(resource.Kind)] = true
}
}
return ot, nil
}
// ObjectKinds returns a slice of one element with the
// group,version,kind of the provided object, or an error if the
// object is not *runtime.Unstructured or has no group,version,kind
// information.
func (ot *ObjectTyper) ObjectKinds(obj runtime.Object) ([]unversioned.GroupVersionKind, bool, error) {
if _, ok := obj.(*runtime.Unstructured); !ok {
return nil, false, fmt.Errorf("type %T is invalid for dynamic object typer", obj)
}
return []unversioned.GroupVersionKind{obj.GetObjectKind().GroupVersionKind()}, false, nil
}
// Recognizes returns true if the provided group,version,kind was in
// the discovery information.
func (ot *ObjectTyper) Recognizes(gvk unversioned.GroupVersionKind) bool {
return ot.registered[gvk]
}

View file

@ -18,6 +18,8 @@ package internalclientset
import (
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
unversionedauthentication "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/authentication/unversioned"
unversionedauthorization "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/authorization/unversioned"
unversionedautoscaling "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/autoscaling/unversioned"
unversionedbatch "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/batch/unversioned"
unversionedcore "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/unversioned"
@ -46,11 +48,21 @@ func FromUnversionedClient(c *unversioned.Client) *internalclientset.Clientset {
} else {
clientset.BatchClient = unversionedbatch.New(nil)
}
if c != nil && c.AuthorizationClient != nil {
clientset.AuthorizationClient = unversionedauthorization.New(c.AuthorizationClient.RESTClient)
} else {
clientset.AuthorizationClient = unversionedauthorization.New(nil)
}
if c != nil && c.AutoscalingClient != nil {
clientset.AutoscalingClient = unversionedautoscaling.New(c.AutoscalingClient.RESTClient)
} else {
clientset.AutoscalingClient = unversionedautoscaling.New(nil)
}
if c != nil && c.AuthenticationClient != nil {
clientset.AuthenticationClient = unversionedauthentication.New(c.AuthenticationClient.RESTClient)
} else {
clientset.AuthenticationClient = unversionedauthentication.New(nil)
}
if c != nil && c.DiscoveryClient != nil {
clientset.DiscoveryClient = discovery.NewDiscoveryClient(c.DiscoveryClient.RESTClient)
} else {

View file

@ -17,8 +17,6 @@ limitations under the License.
package unversioned
import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apimachinery/registered"
"k8s.io/kubernetes/pkg/apis/apps"
"k8s.io/kubernetes/pkg/client/restclient"
)
@ -38,7 +36,7 @@ func (c *AppsClient) PetSets(namespace string) PetSetInterface {
func NewApps(c *restclient.Config) (*AppsClient, error) {
config := *c
if err := setAppsDefaults(&config); err != nil {
if err := setGroupDefaults(apps.GroupName, &config); err != nil {
return nil, err
}
client, err := restclient.RESTClientFor(&config)
@ -55,22 +53,3 @@ func NewAppsOrDie(c *restclient.Config) *AppsClient {
}
return client
}
func setAppsDefaults(config *restclient.Config) error {
g, err := registered.Group(apps.GroupName)
if err != nil {
return err
}
config.APIPath = defaultAPIPath
if config.UserAgent == "" {
config.UserAgent = restclient.DefaultKubernetesUserAgent()
}
// TODO: Unconditionally set the config.Version, until we fix the config.
//if config.Version == "" {
copyGroupVersion := g.GroupVersion
config.GroupVersion = &copyGroupVersion
//}
config.NegotiatedSerializer = api.Codecs
return nil
}

View file

@ -0,0 +1,77 @@
/*
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 unversioned
import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apimachinery/registered"
"k8s.io/kubernetes/pkg/apis/authentication"
"k8s.io/kubernetes/pkg/client/restclient"
)
type AuthenticationInterface interface {
TokenReviewsInterface
}
// AuthenticationClient is used to interact with Kubernetes authentication features.
type AuthenticationClient struct {
*restclient.RESTClient
}
func (c *AuthenticationClient) TokenReviews() TokenReviewInterface {
return newTokenReviews(c)
}
func NewAuthentication(c *restclient.Config) (*AuthenticationClient, error) {
config := *c
if err := setAuthenticationDefaults(&config); err != nil {
return nil, err
}
client, err := restclient.RESTClientFor(&config)
if err != nil {
return nil, err
}
return &AuthenticationClient{client}, nil
}
func NewAuthenticationOrDie(c *restclient.Config) *AuthenticationClient {
client, err := NewAuthentication(c)
if err != nil {
panic(err)
}
return client
}
func setAuthenticationDefaults(config *restclient.Config) error {
// if authentication group is not registered, return an error
g, err := registered.Group(authentication.GroupName)
if err != nil {
return err
}
config.APIPath = defaultAPIPath
if config.UserAgent == "" {
config.UserAgent = restclient.DefaultKubernetesUserAgent()
}
// TODO: Unconditionally set the config.Version, until we fix the config.
//if config.Version == "" {
copyGroupVersion := g.GroupVersion
config.GroupVersion = &copyGroupVersion
//}
config.NegotiatedSerializer = api.Codecs
return nil
}

View file

@ -0,0 +1,77 @@
/*
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 unversioned
import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apimachinery/registered"
"k8s.io/kubernetes/pkg/apis/authorization"
"k8s.io/kubernetes/pkg/client/restclient"
)
type AuthorizationInterface interface {
SubjectAccessReviewsInterface
}
// AuthorizationClient is used to interact with Kubernetes authorization features.
type AuthorizationClient struct {
*restclient.RESTClient
}
func (c *AuthorizationClient) SubjectAccessReviews() SubjectAccessReviewInterface {
return newSubjectAccessReviews(c)
}
func NewAuthorization(c *restclient.Config) (*AuthorizationClient, error) {
config := *c
if err := setAuthorizationDefaults(&config); err != nil {
return nil, err
}
client, err := restclient.RESTClientFor(&config)
if err != nil {
return nil, err
}
return &AuthorizationClient{client}, nil
}
func NewAuthorizationOrDie(c *restclient.Config) *AuthorizationClient {
client, err := NewAuthorization(c)
if err != nil {
panic(err)
}
return client
}
func setAuthorizationDefaults(config *restclient.Config) error {
// if authorization group is not registered, return an error
g, err := registered.Group(authorization.GroupName)
if err != nil {
return err
}
config.APIPath = defaultAPIPath
if config.UserAgent == "" {
config.UserAgent = restclient.DefaultKubernetesUserAgent()
}
// TODO: Unconditionally set the config.Version, until we fix the config.
//if config.Version == "" {
copyGroupVersion := g.GroupVersion
config.GroupVersion = &copyGroupVersion
//}
config.NegotiatedSerializer = api.Codecs
return nil
}

View file

@ -17,8 +17,6 @@ limitations under the License.
package unversioned
import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apimachinery/registered"
"k8s.io/kubernetes/pkg/apis/autoscaling"
"k8s.io/kubernetes/pkg/client/restclient"
)
@ -38,7 +36,7 @@ func (c *AutoscalingClient) HorizontalPodAutoscalers(namespace string) Horizonta
func NewAutoscaling(c *restclient.Config) (*AutoscalingClient, error) {
config := *c
if err := setAutoscalingDefaults(&config); err != nil {
if err := setGroupDefaults(autoscaling.GroupName, &config); err != nil {
return nil, err
}
client, err := restclient.RESTClientFor(&config)
@ -55,23 +53,3 @@ func NewAutoscalingOrDie(c *restclient.Config) *AutoscalingClient {
}
return client
}
func setAutoscalingDefaults(config *restclient.Config) error {
// if autoscaling group is not registered, return an error
g, err := registered.Group(autoscaling.GroupName)
if err != nil {
return err
}
config.APIPath = defaultAPIPath
if config.UserAgent == "" {
config.UserAgent = restclient.DefaultKubernetesUserAgent()
}
// TODO: Unconditionally set the config.Version, until we fix the config.
//if config.Version == "" {
copyGroupVersion := g.GroupVersion
config.GroupVersion = &copyGroupVersion
//}
config.NegotiatedSerializer = api.Codecs
return nil
}

View file

@ -17,11 +17,7 @@ limitations under the License.
package unversioned
import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/apimachinery/registered"
"k8s.io/kubernetes/pkg/apis/batch"
"k8s.io/kubernetes/pkg/apis/batch/v2alpha1"
"k8s.io/kubernetes/pkg/client/restclient"
)
@ -45,19 +41,7 @@ func (c *BatchClient) ScheduledJobs(namespace string) ScheduledJobInterface {
func NewBatch(c *restclient.Config) (*BatchClient, error) {
config := *c
if err := setBatchDefaults(&config, nil); err != nil {
return nil, err
}
client, err := restclient.RESTClientFor(&config)
if err != nil {
return nil, err
}
return &BatchClient{client}, nil
}
func NewBatchV2Alpha1(c *restclient.Config) (*BatchClient, error) {
config := *c
if err := setBatchDefaults(&config, &v2alpha1.SchemeGroupVersion); err != nil {
if err := setGroupDefaults(batch.GroupName, &config); err != nil {
return nil, err
}
client, err := restclient.RESTClientFor(&config)
@ -68,40 +52,9 @@ func NewBatchV2Alpha1(c *restclient.Config) (*BatchClient, error) {
}
func NewBatchOrDie(c *restclient.Config) *BatchClient {
var (
client *BatchClient
err error
)
if c.ContentConfig.GroupVersion != nil && *c.ContentConfig.GroupVersion == v2alpha1.SchemeGroupVersion {
client, err = NewBatchV2Alpha1(c)
} else {
client, err = NewBatch(c)
}
client, err := NewBatch(c)
if err != nil {
panic(err)
}
return client
}
func setBatchDefaults(config *restclient.Config, gv *unversioned.GroupVersion) error {
// if batch group is not registered, return an error
g, err := registered.Group(batch.GroupName)
if err != nil {
return err
}
config.APIPath = defaultAPIPath
if config.UserAgent == "" {
config.UserAgent = restclient.DefaultKubernetesUserAgent()
}
// TODO: Unconditionally set the config.Version, until we fix the config.
//if config.Version == "" {
copyGroupVersion := g.GroupVersion
if gv != nil {
copyGroupVersion = *gv
}
config.GroupVersion = &copyGroupVersion
//}
config.NegotiatedSerializer = api.Codecs
return nil
}

View file

@ -17,8 +17,6 @@ limitations under the License.
package unversioned
import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apimachinery/registered"
"k8s.io/kubernetes/pkg/apis/certificates"
"k8s.io/kubernetes/pkg/client/restclient"
)
@ -60,22 +58,7 @@ func NewCertificatesOrDie(c *restclient.Config) *CertificatesClient {
}
func setCertificatesDefaults(config *restclient.Config) error {
// if certificates group is not registered, return an error
g, err := registered.Group(certificates.GroupName)
if err != nil {
return err
}
config.APIPath = defaultAPIPath
if config.UserAgent == "" {
config.UserAgent = restclient.DefaultKubernetesUserAgent()
}
// TODO: Unconditionally set the config.Version, until we fix the config.
//if config.Version == "" {
copyGroupVersion := g.GroupVersion
config.GroupVersion = &copyGroupVersion
//}
config.NegotiatedSerializer = api.Codecs
setGroupDefaults(certificates.GroupName, config)
if config.QPS == 0 {
config.QPS = 5
}

View file

@ -44,7 +44,10 @@ type Interface interface {
PersistentVolumeClaimsNamespacer
ComponentStatusesInterface
ConfigMapsNamespacer
Apps() AppsInterface
Authorization() AuthorizationInterface
Autoscaling() AutoscalingInterface
Authentication() AuthenticationInterface
Batch() BatchInterface
Extensions() ExtensionsInterface
Rbac() RbacInterface
@ -118,7 +121,9 @@ func (c *Client) ConfigMaps(namespace string) ConfigMapsInterface {
// Client is the implementation of a Kubernetes client.
type Client struct {
*restclient.RESTClient
*AuthorizationClient
*AutoscalingClient
*AuthenticationClient
*BatchClient
*ExtensionsClient
*AppsClient
@ -150,10 +155,18 @@ func IsTimeout(err error) bool {
return false
}
func (c *Client) Authorization() AuthorizationInterface {
return c.AuthorizationClient
}
func (c *Client) Autoscaling() AutoscalingInterface {
return c.AutoscalingClient
}
func (c *Client) Authentication() AuthenticationInterface {
return c.AuthenticationClient
}
func (c *Client) Batch() BatchInterface {
return c.BatchClient
}
@ -170,6 +183,10 @@ func (c *Client) Rbac() RbacInterface {
return c.RbacClient
}
func (c *Client) Policy() PolicyInterface {
return c.PolicyClient
}
func (c *Client) Discovery() discovery.DiscoveryInterface {
return c.DiscoveryClient
}

View file

@ -19,7 +19,7 @@ package latest
import (
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
_ "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api/v1"
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api/v1"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/runtime/serializer/json"
"k8s.io/kubernetes/pkg/runtime/serializer/versioning"
@ -40,15 +40,27 @@ const OldestVersion = "v1"
// with a set of versions to choose.
var Versions = []string{"v1"}
var Codec runtime.Codec
var (
Codec runtime.Codec
Scheme *runtime.Scheme
)
func init() {
yamlSerializer := json.NewYAMLSerializer(json.DefaultMetaFactory, api.Scheme, api.Scheme)
Scheme = runtime.NewScheme()
if err := api.AddToScheme(Scheme); err != nil {
// Programmer error, detect immediately
panic(err)
}
if err := v1.AddToScheme(Scheme); err != nil {
// Programmer error, detect immediately
panic(err)
}
yamlSerializer := json.NewYAMLSerializer(json.DefaultMetaFactory, Scheme, Scheme)
Codec = versioning.NewCodecForScheme(
api.Scheme,
Scheme,
yamlSerializer,
yamlSerializer,
[]unversioned.GroupVersion{{Version: Version}},
[]unversioned.GroupVersion{{Version: runtime.APIVersionInternal}},
unversioned.GroupVersion{Version: Version},
runtime.InternalGroupVersioner,
)
}

View file

@ -21,17 +21,20 @@ import (
"k8s.io/kubernetes/pkg/runtime"
)
// Scheme is the default instance of runtime.Scheme to which types in the Kubernetes API are already registered.
var Scheme = runtime.NewScheme()
// SchemeGroupVersion is group version used to register these objects
// TODO this should be in the "kubeconfig" group
var SchemeGroupVersion = unversioned.GroupVersion{Group: "", Version: runtime.APIVersionInternal}
func init() {
Scheme.AddKnownTypes(SchemeGroupVersion,
var (
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
AddToScheme = SchemeBuilder.AddToScheme
)
func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&Config{},
)
return nil
}
func (obj *Config) GetObjectKind() unversioned.ObjectKind { return obj }

View file

@ -88,6 +88,8 @@ type AuthInfo struct {
ClientKeyData []byte `json:"client-key-data,omitempty"`
// Token is the bearer token for authentication to the kubernetes cluster.
Token string `json:"token,omitempty"`
// TokenFile is a pointer to a file that contains a bearer token (as described above). If both Token and TokenFile are present, Token takes precedence.
TokenFile string `json:"tokenFile,omitempty"`
// Impersonate is the username to act-as.
Impersonate string `json:"act-as,omitempty"`
// Username is the username for basic authentication to the kubernetes cluster.

View file

@ -24,8 +24,8 @@ import (
"k8s.io/kubernetes/pkg/runtime"
)
func init() {
err := api.Scheme.AddConversionFuncs(
func addConversionFuncs(scheme *runtime.Scheme) error {
return scheme.AddConversionFuncs(
func(in *Cluster, out *api.Cluster, s conversion.Scope) error {
return s.DefaultConvert(in, out, conversion.IgnoreMissingFields)
},
@ -224,8 +224,4 @@ func init() {
return nil
},
)
if err != nil {
// If one of the conversion functions is malformed, detect it immediately.
panic(err)
}
}

View file

@ -18,17 +18,23 @@ package v1
import (
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
"k8s.io/kubernetes/pkg/runtime"
)
// SchemeGroupVersion is group version used to register these objects
// TODO this should be in the "kubeconfig" group
var SchemeGroupVersion = unversioned.GroupVersion{Group: "", Version: "v1"}
func init() {
api.Scheme.AddKnownTypes(SchemeGroupVersion,
var (
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes, addConversionFuncs)
AddToScheme = SchemeBuilder.AddToScheme
)
func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&Config{},
)
return nil
}
func (obj *Config) GetObjectKind() unversioned.ObjectKind { return obj }

View file

@ -82,6 +82,8 @@ type AuthInfo struct {
ClientKeyData []byte `json:"client-key-data,omitempty"`
// Token is the bearer token for authentication to the kubernetes cluster.
Token string `json:"token,omitempty"`
// TokenFile is a pointer to a file that contains a bearer token (as described above). If both Token and TokenFile are present, Token takes precedence.
TokenFile string `json:"tokenFile,omitempty"`
// Impersonate is the username to imperonate. The name matches the flag.
Impersonate string `json:"as,omitempty"`
// Username is the username for basic authentication to the kubernetes cluster.

View file

@ -167,6 +167,12 @@ func getUserIdentificationPartialConfig(configAuthInfo clientcmdapi.AuthInfo, fa
// blindly overwrite existing values based on precedence
if len(configAuthInfo.Token) > 0 {
mergedConfig.BearerToken = configAuthInfo.Token
} else if len(configAuthInfo.TokenFile) > 0 {
tokenBytes, err := ioutil.ReadFile(configAuthInfo.TokenFile)
if err != nil {
return nil, err
}
mergedConfig.BearerToken = string(tokenBytes)
}
if len(configAuthInfo.Impersonate) > 0 {
mergedConfig.Impersonate = configAuthInfo.Impersonate

View file

@ -85,7 +85,7 @@ func (g *ClientConfigGetter) GetLoadingPrecedence() []string {
return nil
}
func (g *ClientConfigGetter) GetStartingConfig() (*clientcmdapi.Config, error) {
return nil, nil
return g.kubeconfigGetter()
}
func (g *ClientConfigGetter) GetDefaultFilename() string {
return ""
@ -215,7 +215,6 @@ func (rules *ClientConfigLoadingRules) Load() (*clientcmdapi.Config, error) {
errlist = append(errlist, err)
}
}
return config, utilerrors.NewAggregate(errlist)
}
@ -530,7 +529,7 @@ func GetClusterFileReferences(cluster *clientcmdapi.Cluster) []*string {
}
func GetAuthInfoFileReferences(authInfo *clientcmdapi.AuthInfo) []*string {
return []*string{&authInfo.ClientCertificate, &authInfo.ClientKey}
return []*string{&authInfo.ClientCertificate, &authInfo.ClientKey, &authInfo.TokenFile}
}
// ResolvePaths updates the given refs to be absolute paths, relative to the given base directory

View file

@ -158,7 +158,7 @@ func RecommendedContextOverrideFlags(prefix string) ContextOverrideFlags {
return ContextOverrideFlags{
ClusterName: FlagInfo{prefix + FlagClusterName, "", "", "The name of the kubeconfig cluster to use"},
AuthInfoName: FlagInfo{prefix + FlagAuthInfoName, "", "", "The name of the kubeconfig user to use"},
Namespace: FlagInfo{prefix + FlagNamespace, "", "", "If present, the namespace scope for this CLI request"},
Namespace: FlagInfo{prefix + FlagNamespace, "n", "", "If present, the namespace scope for this CLI request"},
}
}

View file

@ -22,6 +22,7 @@ import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/errors"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/apis/apps"
"k8s.io/kubernetes/pkg/apis/batch"
"k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/util/wait"
@ -72,6 +73,17 @@ func ReplicaSetHasDesiredReplicas(c ExtensionsInterface, replicaSet *extensions.
}
}
func PetSetHasDesiredPets(c AppsInterface, petset *apps.PetSet) wait.ConditionFunc {
// TODO: Differentiate between 0 pets and a really quick scale down using generation.
return func() (bool, error) {
ps, err := c.PetSets(petset.Namespace).Get(petset.Name)
if err != nil {
return false, err
}
return ps.Status.Replicas == ps.Spec.Replicas, nil
}
}
// JobHasDesiredParallelism returns a condition that will be true if the desired parallelism count
// for a job equals the current active counts or is less by an appropriate successful/unsuccessful count.
func JobHasDesiredParallelism(c BatchInterface, job *batch.Job) wait.ConditionFunc {
@ -121,6 +133,10 @@ func DeploymentHasDesiredReplicas(c ExtensionsInterface, deployment *extensions.
// the pod has already reached completed state.
var ErrPodCompleted = fmt.Errorf("pod ran to completion")
// ErrContainerTerminated is returned by PodContainerRunning in the intermediate
// state where the pod indicates it's still running, but its container is already terminated
var ErrContainerTerminated = fmt.Errorf("container terminated")
// PodRunning returns true if the pod is running, false if the pod has not yet reached running state,
// returns ErrPodCompleted if the pod has run to completion, or an error in any other case.
func PodRunning(event watch.Event) (bool, error) {
@ -217,6 +233,9 @@ func PodContainerRunning(containerName string) watch.ConditionFunc {
if s.Name != containerName {
continue
}
if s.State.Terminated != nil {
return false, ErrContainerTerminated
}
return s.State.Running != nil, nil
}
return false, nil

View file

@ -17,8 +17,6 @@ limitations under the License.
package unversioned
import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apimachinery/registered"
"k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/client/restclient"
)
@ -37,6 +35,7 @@ type ExtensionsInterface interface {
ThirdPartyResourceNamespacer
ReplicaSetsNamespacer
PodSecurityPoliciesInterface
StorageClassesInterface
}
// ExtensionsClient is used to interact with experimental Kubernetes features.
@ -82,13 +81,17 @@ func (c *ExtensionsClient) ReplicaSets(namespace string) ReplicaSetInterface {
return newReplicaSets(c, namespace)
}
func (c *ExtensionsClient) StorageClasses() StorageClassInterface {
return newStorageClasses(c)
}
// NewExtensions creates a new ExtensionsClient for the given config. This client
// provides access to experimental Kubernetes features.
// Features of Extensions group are not supported and may be changed or removed in
// incompatible ways at any time.
func NewExtensions(c *restclient.Config) (*ExtensionsClient, error) {
config := *c
if err := setExtensionsDefaults(&config); err != nil {
if err := setGroupDefaults(extensions.GroupName, &config); err != nil {
return nil, err
}
client, err := restclient.RESTClientFor(&config)
@ -109,23 +112,3 @@ func NewExtensionsOrDie(c *restclient.Config) *ExtensionsClient {
}
return client
}
func setExtensionsDefaults(config *restclient.Config) error {
// if experimental group is not registered, return an error
g, err := registered.Group(extensions.GroupName)
if err != nil {
return err
}
config.APIPath = defaultAPIPath
if config.UserAgent == "" {
config.UserAgent = restclient.DefaultKubernetesUserAgent()
}
// TODO: Unconditionally set the config.Version, until we fix the config.
//if config.Version == "" {
copyGroupVersion := g.GroupVersion
config.GroupVersion = &copyGroupVersion
//}
config.NegotiatedSerializer = api.Codecs
return nil
}

View file

@ -23,6 +23,8 @@ import (
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/apimachinery/registered"
"k8s.io/kubernetes/pkg/apis/apps"
"k8s.io/kubernetes/pkg/apis/authentication"
"k8s.io/kubernetes/pkg/apis/authorization"
"k8s.io/kubernetes/pkg/apis/autoscaling"
"k8s.io/kubernetes/pkg/apis/batch"
"k8s.io/kubernetes/pkg/apis/certificates"
@ -62,6 +64,15 @@ func New(c *restclient.Config) (*Client, error) {
return nil, err
}
var authorizationClient *AuthorizationClient
if registered.IsRegistered(authorization.GroupName) {
authorizationConfig := *c
authorizationClient, err = NewAuthorization(&authorizationConfig)
if err != nil {
return nil, err
}
}
var autoscalingClient *AutoscalingClient
if registered.IsRegistered(autoscaling.GroupName) {
autoscalingConfig := *c
@ -71,6 +82,15 @@ func New(c *restclient.Config) (*Client, error) {
}
}
var authenticationClient *AuthenticationClient
if registered.IsRegistered(authentication.GroupName) {
authenticationConfig := *c
authenticationClient, err = NewAuthentication(&authenticationConfig)
if err != nil {
return nil, err
}
}
var batchClient *BatchClient
if registered.IsRegistered(batch.GroupName) {
batchConfig := *c
@ -123,7 +143,19 @@ func New(c *restclient.Config) (*Client, error) {
}
}
return &Client{RESTClient: client, AutoscalingClient: autoscalingClient, BatchClient: batchClient, CertificatesClient: certsClient, ExtensionsClient: extensionsClient, DiscoveryClient: discoveryClient, AppsClient: appsClient, PolicyClient: policyClient, RbacClient: rbacClient}, nil
return &Client{
RESTClient: client,
AppsClient: appsClient,
AuthenticationClient: authenticationClient,
AuthorizationClient: authorizationClient,
AutoscalingClient: autoscalingClient,
BatchClient: batchClient,
CertificatesClient: certsClient,
DiscoveryClient: discoveryClient,
ExtensionsClient: extensionsClient,
PolicyClient: policyClient,
RbacClient: rbacClient,
}, nil
}
// MatchesServerVersion queries the server to compares the build version
@ -258,16 +290,35 @@ func SetKubernetesDefaults(config *restclient.Config) error {
if config.APIPath == "" {
config.APIPath = legacyAPIPath
}
g, err := registered.Group(api.GroupName)
if err != nil {
return err
if config.GroupVersion == nil || config.GroupVersion.Group != api.GroupName {
g, err := registered.Group(api.GroupName)
if err != nil {
return err
}
copyGroupVersion := g.GroupVersion
config.GroupVersion = &copyGroupVersion
}
// TODO: Unconditionally set the config.Version, until we fix the config.
copyGroupVersion := g.GroupVersion
config.GroupVersion = &copyGroupVersion
if config.NegotiatedSerializer == nil {
config.NegotiatedSerializer = api.Codecs
}
return restclient.SetKubernetesDefaults(config)
}
func setGroupDefaults(groupName string, config *restclient.Config) error {
config.APIPath = defaultAPIPath
if config.UserAgent == "" {
config.UserAgent = restclient.DefaultKubernetesUserAgent()
}
if config.GroupVersion == nil || config.GroupVersion.Group != groupName {
g, err := registered.Group(groupName)
if err != nil {
return err
}
copyGroupVersion := g.GroupVersion
config.GroupVersion = &copyGroupVersion
}
if config.NegotiatedSerializer == nil {
config.NegotiatedSerializer = api.Codecs
}
return nil
}

View file

@ -23,7 +23,7 @@ import (
_ "k8s.io/kubernetes/pkg/api/install"
"k8s.io/kubernetes/pkg/apimachinery/registered"
_ "k8s.io/kubernetes/pkg/apis/apps/install"
_ "k8s.io/kubernetes/pkg/apis/authentication.k8s.io/install"
_ "k8s.io/kubernetes/pkg/apis/authentication/install"
_ "k8s.io/kubernetes/pkg/apis/authorization/install"
_ "k8s.io/kubernetes/pkg/apis/autoscaling/install"
_ "k8s.io/kubernetes/pkg/apis/batch/install"

View file

@ -17,8 +17,6 @@ limitations under the License.
package unversioned
import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apimachinery/registered"
"k8s.io/kubernetes/pkg/apis/policy"
"k8s.io/kubernetes/pkg/client/restclient"
)
@ -38,7 +36,7 @@ func (c *PolicyClient) PodDisruptionBudgets(namespace string) PodDisruptionBudge
func NewPolicy(c *restclient.Config) (*PolicyClient, error) {
config := *c
if err := setPolicyDefaults(&config); err != nil {
if err := setGroupDefaults(policy.GroupName, &config); err != nil {
return nil, err
}
client, err := restclient.RESTClientFor(&config)
@ -55,22 +53,3 @@ func NewPolicyOrDie(c *restclient.Config) *PolicyClient {
}
return client
}
func setPolicyDefaults(config *restclient.Config) error {
g, err := registered.Group(policy.GroupName)
if err != nil {
return err
}
config.APIPath = defaultAPIPath
if config.UserAgent == "" {
config.UserAgent = restclient.DefaultKubernetesUserAgent()
}
// TODO: Unconditionally set the config.Version, until we fix the config.
//if config.Version == "" {
copyGroupVersion := g.GroupVersion
config.GroupVersion = &copyGroupVersion
//}
config.NegotiatedSerializer = api.Codecs
return nil
}

View file

@ -17,8 +17,6 @@ limitations under the License.
package unversioned
import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apimachinery/registered"
"k8s.io/kubernetes/pkg/apis/rbac"
"k8s.io/kubernetes/pkg/client/restclient"
)
@ -54,7 +52,7 @@ func (c *RbacClient) ClusterRoles() ClusterRoleInterface {
// NewRbac creates a new RbacClient for the given config.
func NewRbac(c *restclient.Config) (*RbacClient, error) {
config := *c
if err := setRbacDefaults(&config); err != nil {
if err := setGroupDefaults(rbac.GroupName, &config); err != nil {
return nil, err
}
client, err := restclient.RESTClientFor(&config)
@ -73,24 +71,3 @@ func NewRbacOrDie(c *restclient.Config) *RbacClient {
}
return client
}
func setRbacDefaults(config *restclient.Config) error {
// if rbac group is not registered, return an error
g, err := registered.Group(rbac.GroupName)
if err != nil {
return err
}
config.APIPath = defaultAPIPath
if config.UserAgent == "" {
config.UserAgent = restclient.DefaultKubernetesUserAgent()
}
// TODO: Unconditionally set the config.Version, until we fix the config.
//if config.Version == "" {
copyGroupVersion := g.GroupVersion
config.GroupVersion = &copyGroupVersion
//}
config.NegotiatedSerializer = api.Codecs
return nil
}

View file

@ -33,7 +33,7 @@ type ReplicationControllerInterface interface {
Create(ctrl *api.ReplicationController) (*api.ReplicationController, error)
Update(ctrl *api.ReplicationController) (*api.ReplicationController, error)
UpdateStatus(ctrl *api.ReplicationController) (*api.ReplicationController, error)
Delete(name string) error
Delete(name string, options *api.DeleteOptions) error
Watch(opts api.ListOptions) (watch.Interface, error)
}
@ -84,8 +84,8 @@ func (c *replicationControllers) UpdateStatus(controller *api.ReplicationControl
}
// Delete deletes an existing replication controller.
func (c *replicationControllers) Delete(name string) error {
return c.r.Delete().Namespace(c.ns).Resource("replicationControllers").Name(name).Do().Error()
func (c *replicationControllers) Delete(name string, options *api.DeleteOptions) error {
return c.r.Delete().Namespace(c.ns).Resource("replicationControllers").Name(name).Body(options).Do().Error()
}
// Watch returns a watch.Interface that watches the requested controllers.

View file

@ -55,34 +55,34 @@ var _ ScheduledJobInterface = &scheduledJobs{}
// List returns a list of scheduled jobs that match the label and field selectors.
func (c *scheduledJobs) List(opts api.ListOptions) (result *batch.ScheduledJobList, err error) {
result = &batch.ScheduledJobList{}
err = c.r.Get().Namespace(c.ns).Resource("scheduledJobs").VersionedParams(&opts, api.ParameterCodec).Do().Into(result)
err = c.r.Get().Namespace(c.ns).Resource("scheduledjobs").VersionedParams(&opts, api.ParameterCodec).Do().Into(result)
return
}
// Get returns information about a particular scheduled job.
func (c *scheduledJobs) Get(name string) (result *batch.ScheduledJob, err error) {
result = &batch.ScheduledJob{}
err = c.r.Get().Namespace(c.ns).Resource("scheduledJobs").Name(name).Do().Into(result)
err = c.r.Get().Namespace(c.ns).Resource("scheduledjobs").Name(name).Do().Into(result)
return
}
// Create creates a new scheduled job.
func (c *scheduledJobs) Create(job *batch.ScheduledJob) (result *batch.ScheduledJob, err error) {
result = &batch.ScheduledJob{}
err = c.r.Post().Namespace(c.ns).Resource("scheduledJobs").Body(job).Do().Into(result)
err = c.r.Post().Namespace(c.ns).Resource("scheduledjobs").Body(job).Do().Into(result)
return
}
// Update updates an existing scheduled job.
func (c *scheduledJobs) Update(job *batch.ScheduledJob) (result *batch.ScheduledJob, err error) {
result = &batch.ScheduledJob{}
err = c.r.Put().Namespace(c.ns).Resource("scheduledJobs").Name(job.Name).Body(job).Do().Into(result)
err = c.r.Put().Namespace(c.ns).Resource("scheduledjobs").Name(job.Name).Body(job).Do().Into(result)
return
}
// Delete deletes a scheduled job, returns error if one occurs.
func (c *scheduledJobs) Delete(name string, options *api.DeleteOptions) (err error) {
return c.r.Delete().Namespace(c.ns).Resource("scheduledJobs").Name(name).Body(options).Do().Error()
return c.r.Delete().Namespace(c.ns).Resource("scheduledjobs").Name(name).Body(options).Do().Error()
}
// Watch returns a watch.Interface that watches the requested scheduled jobs.
@ -90,7 +90,7 @@ func (c *scheduledJobs) Watch(opts api.ListOptions) (watch.Interface, error) {
return c.r.Get().
Prefix("watch").
Namespace(c.ns).
Resource("scheduledJobs").
Resource("scheduledjobs").
VersionedParams(&opts, api.ParameterCodec).
Watch()
}
@ -98,6 +98,6 @@ func (c *scheduledJobs) Watch(opts api.ListOptions) (watch.Interface, error) {
// UpdateStatus takes the name of the scheduled job and the new status. Returns the server's representation of the scheduled job, and an error, if it occurs.
func (c *scheduledJobs) UpdateStatus(job *batch.ScheduledJob) (result *batch.ScheduledJob, err error) {
result = &batch.ScheduledJob{}
err = c.r.Put().Namespace(c.ns).Resource("scheduledJobs").Name(job.Name).SubResource("status").Body(job).Do().Into(result)
err = c.r.Put().Namespace(c.ns).Resource("scheduledjobs").Name(job.Name).SubResource("status").Body(job).Do().Into(result)
return
}

View file

@ -0,0 +1,87 @@
/*
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 unversioned
import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/watch"
)
type StorageClassesInterface interface {
StorageClasses() StorageClassInterface
}
// StorageClassInterface has methods to work with StorageClass resources.
type StorageClassInterface interface {
List(opts api.ListOptions) (*extensions.StorageClassList, error)
Get(name string) (*extensions.StorageClass, error)
Create(storageClass *extensions.StorageClass) (*extensions.StorageClass, error)
Update(storageClass *extensions.StorageClass) (*extensions.StorageClass, error)
Delete(name string) error
Watch(opts api.ListOptions) (watch.Interface, error)
}
// storageClasses implements StorageClassInterface
type storageClasses struct {
client *ExtensionsClient
}
func newStorageClasses(c *ExtensionsClient) *storageClasses {
return &storageClasses{c}
}
func (c *storageClasses) List(opts api.ListOptions) (result *extensions.StorageClassList, err error) {
result = &extensions.StorageClassList{}
err = c.client.Get().
Resource("storageclasses").
VersionedParams(&opts, api.ParameterCodec).
Do().
Into(result)
return result, err
}
func (c *storageClasses) Get(name string) (result *extensions.StorageClass, err error) {
result = &extensions.StorageClass{}
err = c.client.Get().Resource("storageClasses").Name(name).Do().Into(result)
return
}
func (c *storageClasses) Create(storageClass *extensions.StorageClass) (result *extensions.StorageClass, err error) {
result = &extensions.StorageClass{}
err = c.client.Post().Resource("storageClasses").Body(storageClass).Do().Into(result)
return
}
func (c *storageClasses) Update(storageClass *extensions.StorageClass) (result *extensions.StorageClass, err error) {
result = &extensions.StorageClass{}
err = c.client.Put().Resource("storageClasses").Name(storageClass.Name).Body(storageClass).Do().Into(result)
return
}
func (c *storageClasses) Delete(name string) error {
return c.client.Delete().Resource("storageClasses").Name(name).Do().Error()
}
func (c *storageClasses) Watch(opts api.ListOptions) (watch.Interface, error) {
return c.client.Get().
Prefix("watch").
Resource("storageClasses").
VersionedParams(&opts, api.ParameterCodec).
Watch()
}

View file

@ -0,0 +1,45 @@
/*
Copyright 2015 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 unversioned
import (
"k8s.io/kubernetes/pkg/apis/authorization"
)
type SubjectAccessReviewsInterface interface {
SubjectAccessReviews() SubjectAccessReviewInterface
}
type SubjectAccessReviewInterface interface {
Create(subjectAccessReview *authorization.SubjectAccessReview) (*authorization.SubjectAccessReview, error)
}
type subjectAccessReviews struct {
client *AuthorizationClient
}
func newSubjectAccessReviews(c *AuthorizationClient) *subjectAccessReviews {
return &subjectAccessReviews{
client: c,
}
}
func (c *subjectAccessReviews) Create(subjectAccessReview *authorization.SubjectAccessReview) (result *authorization.SubjectAccessReview, err error) {
result = &authorization.SubjectAccessReview{}
err = c.client.Post().Resource("subjectAccessReviews").Body(subjectAccessReview).Do().Into(result)
return
}

View file

@ -0,0 +1,83 @@
/*
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 testclient
import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/apps"
"k8s.io/kubernetes/pkg/watch"
)
// FakePetSets implements PetSetsInterface. Meant to be embedded into a struct to get a default
// implementation. This makes faking out just the method you want to test easier.
type FakePetSets struct {
Fake *FakeApps
Namespace string
}
func (c *FakePetSets) Get(name string) (*apps.PetSet, error) {
obj, err := c.Fake.Invokes(NewGetAction("petsets", c.Namespace, name), &apps.PetSet{})
if obj == nil {
return nil, err
}
return obj.(*apps.PetSet), err
}
func (c *FakePetSets) List(opts api.ListOptions) (*apps.PetSetList, error) {
obj, err := c.Fake.Invokes(NewListAction("petsets", c.Namespace, opts), &apps.PetSetList{})
if obj == nil {
return nil, err
}
return obj.(*apps.PetSetList), err
}
func (c *FakePetSets) Create(rs *apps.PetSet) (*apps.PetSet, error) {
obj, err := c.Fake.Invokes(NewCreateAction("petsets", c.Namespace, rs), rs)
if obj == nil {
return nil, err
}
return obj.(*apps.PetSet), err
}
func (c *FakePetSets) Update(rs *apps.PetSet) (*apps.PetSet, error) {
obj, err := c.Fake.Invokes(NewUpdateAction("petsets", c.Namespace, rs), rs)
if obj == nil {
return nil, err
}
return obj.(*apps.PetSet), err
}
func (c *FakePetSets) Delete(name string, options *api.DeleteOptions) error {
_, err := c.Fake.Invokes(NewDeleteAction("petsets", c.Namespace, name), &apps.PetSet{})
return err
}
func (c *FakePetSets) Watch(opts api.ListOptions) (watch.Interface, error) {
return c.Fake.InvokesWatch(NewWatchAction("petsets", c.Namespace, opts))
}
func (c *FakePetSets) UpdateStatus(rs *apps.PetSet) (result *apps.PetSet, err error) {
obj, err := c.Fake.Invokes(NewUpdateSubresourceAction("petsets", "status", c.Namespace, rs), rs)
if obj == nil {
return nil, err
}
return obj.(*apps.PetSet), err
}

View file

@ -72,7 +72,7 @@ func (c *FakeReplicationControllers) UpdateStatus(controller *api.ReplicationCon
return obj.(*api.ReplicationController), err
}
func (c *FakeReplicationControllers) Delete(name string) error {
func (c *FakeReplicationControllers) Delete(name string, options *api.DeleteOptions) error {
_, err := c.Fake.Invokes(NewDeleteAction("replicationcontrollers", c.Namespace, name), &api.ReplicationController{})
return err
}

View file

@ -0,0 +1,74 @@
/*
Copyright 2015 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 testclient
import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/extensions"
kclientlib "k8s.io/kubernetes/pkg/client/unversioned"
"k8s.io/kubernetes/pkg/watch"
)
// FakeStorageClasses implements StorageClassInterface. Meant to be embedded into a struct to get a default
// implementation. This makes faking out just the method you want to test easier.
type FakeStorageClasses struct {
Fake *FakeExperimental
}
// Ensure statically that FakeStorageClasses implements StorageClassInterface.
var _ kclientlib.StorageClassInterface = &FakeStorageClasses{}
func (c *FakeStorageClasses) Get(name string) (*extensions.StorageClass, error) {
obj, err := c.Fake.Invokes(NewGetAction("storageclasses", "", name), &extensions.StorageClass{})
if obj == nil {
return nil, err
}
return obj.(*extensions.StorageClass), err
}
func (c *FakeStorageClasses) List(opts api.ListOptions) (*extensions.StorageClassList, error) {
obj, err := c.Fake.Invokes(NewListAction("storageclasses", "", opts), &extensions.StorageClassList{})
if obj == nil {
return nil, err
}
return obj.(*extensions.StorageClassList), err
}
func (c *FakeStorageClasses) Create(np *extensions.StorageClass) (*extensions.StorageClass, error) {
obj, err := c.Fake.Invokes(NewCreateAction("storageclasses", "", np), &extensions.StorageClass{})
if obj == nil {
return nil, err
}
return obj.(*extensions.StorageClass), err
}
func (c *FakeStorageClasses) Update(np *extensions.StorageClass) (*extensions.StorageClass, error) {
obj, err := c.Fake.Invokes(NewUpdateAction("storageclasses", "", np), &extensions.StorageClass{})
if obj == nil {
return nil, err
}
return obj.(*extensions.StorageClass), err
}
func (c *FakeStorageClasses) Delete(name string) error {
_, err := c.Fake.Invokes(NewDeleteAction("storageclasses", "", name), &extensions.StorageClass{})
return err
}
func (c *FakeStorageClasses) Watch(opts api.ListOptions) (watch.Interface, error) {
return c.Fake.InvokesWatch(NewWatchAction("storageclasses", "", opts))
}

View file

@ -0,0 +1,36 @@
/*
Copyright 2015 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 testclient
import (
"k8s.io/kubernetes/pkg/apis/authorization"
)
// FakeSubjectAccessReviews implements SubjectAccessReviewInterface. Meant to be embedded into a struct to get a default
// implementation. This makes faking out just the methods you want to test easier.
type FakeSubjectAccessReviews struct {
Fake *FakeAuthorization
}
func (c *FakeSubjectAccessReviews) Create(a *authorization.SubjectAccessReview) (*authorization.SubjectAccessReview, error) {
obj, err := c.Fake.Invokes(NewRootCreateAction("subjectaccessreviews", a), a)
if obj == nil {
return nil, err
}
return obj.(*authorization.SubjectAccessReview), err
}

View file

@ -0,0 +1,35 @@
/*
Copyright 2015 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 testclient
import (
"k8s.io/kubernetes/pkg/apis/authentication"
)
// FakeTokenReviews implements ClusterRoleInterface
type FakeTokenReviews struct {
Fake *FakeAuthentication
}
func (c *FakeTokenReviews) Create(review *authentication.TokenReview) (*authentication.TokenReview, error) {
obj, err := c.Fake.Invokes(NewRootCreateAction("tokenreviews", review), review)
if obj == nil {
return nil, err
}
return obj.(*authentication.TokenReview), err
}

View file

@ -203,7 +203,7 @@ func (c *Fake) InvokesProxy(action Action) restclient.ResponseWrapper {
// ClearActions clears the history of actions called on the fake client
func (c *Fake) ClearActions() {
c.Lock()
c.Unlock()
defer c.Unlock()
c.actions = make([]Action, 0)
}
@ -277,6 +277,14 @@ func (c *Fake) Namespaces() client.NamespaceInterface {
return &FakeNamespaces{Fake: c}
}
func (c *Fake) Apps() client.AppsInterface {
return &FakeApps{c}
}
func (c *Fake) Authorization() client.AuthorizationInterface {
return &FakeAuthorization{c}
}
func (c *Fake) Autoscaling() client.AutoscalingInterface {
return &FakeAutoscaling{c}
}
@ -309,6 +317,10 @@ func (c *Fake) Rbac() client.RbacInterface {
return &FakeRbac{Fake: c}
}
func (c *Fake) Authentication() client.AuthenticationInterface {
return &FakeAuthentication{Fake: c}
}
// SwaggerSchema returns an empty swagger.ApiDeclaration for testing
func (c *Fake) SwaggerSchema(version unversioned.GroupVersion) (*swagger.ApiDeclaration, error) {
action := ActionImpl{}
@ -323,6 +335,32 @@ func (c *Fake) SwaggerSchema(version unversioned.GroupVersion) (*swagger.ApiDecl
return &swagger.ApiDeclaration{}, nil
}
// NewSimpleFakeApps returns a client that will respond with the provided objects
func NewSimpleFakeApps(objects ...runtime.Object) *FakeApps {
return &FakeApps{Fake: NewSimpleFake(objects...)}
}
type FakeApps struct {
*Fake
}
func (c *FakeApps) PetSets(namespace string) client.PetSetInterface {
return &FakePetSets{Fake: c, Namespace: namespace}
}
// NewSimpleFakeAuthorization returns a client that will respond with the provided objects
func NewSimpleFakeAuthorization(objects ...runtime.Object) *FakeAuthorization {
return &FakeAuthorization{Fake: NewSimpleFake(objects...)}
}
type FakeAuthorization struct {
*Fake
}
func (c *FakeAuthorization) SubjectAccessReviews() client.SubjectAccessReviewInterface {
return &FakeSubjectAccessReviews{Fake: c}
}
// NewSimpleFakeAutoscaling returns a client that will respond with the provided objects
func NewSimpleFakeAutoscaling(objects ...runtime.Object) *FakeAutoscaling {
return &FakeAutoscaling{Fake: NewSimpleFake(objects...)}
@ -336,6 +374,18 @@ func (c *FakeAutoscaling) HorizontalPodAutoscalers(namespace string) client.Hori
return &FakeHorizontalPodAutoscalers{Fake: c, Namespace: namespace}
}
func NewSimpleFakeAuthentication(objects ...runtime.Object) *FakeAuthentication {
return &FakeAuthentication{Fake: NewSimpleFake(objects...)}
}
type FakeAuthentication struct {
*Fake
}
func (c *FakeAuthentication) TokenReviews() client.TokenReviewInterface {
return &FakeTokenReviews{Fake: c}
}
// NewSimpleFakeBatch returns a client that will respond with the provided objects
func NewSimpleFakeBatch(objects ...runtime.Object) *FakeBatch {
return &FakeBatch{Fake: NewSimpleFake(objects...)}
@ -394,6 +444,10 @@ func (c *FakeExperimental) NetworkPolicies(namespace string) client.NetworkPolic
return &FakeNetworkPolicies{Fake: c, Namespace: namespace}
}
func (c *FakeExperimental) StorageClasses() client.StorageClassInterface {
return &FakeStorageClasses{Fake: c}
}
func NewSimpleFakeRbac(objects ...runtime.Object) *FakeRbac {
return &FakeRbac{Fake: NewSimpleFake(objects...)}
}

View file

@ -0,0 +1,49 @@
/*
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 unversioned
import (
"k8s.io/kubernetes/pkg/apis/authentication"
)
// TokenReviews has methods to work with TokenReview resources in a namespace
type TokenReviewsInterface interface {
TokenReviews() TokenReviewInterface
}
// TokenReviewInterface has methods to work with TokenReview resources.
type TokenReviewInterface interface {
Create(tokenReview *authentication.TokenReview) (*authentication.TokenReview, error)
}
// tokenReviews implements TokenReviewsNamespacer interface
type tokenReviews struct {
client *AuthenticationClient
}
// newTokenReviews returns a tokenReviews
func newTokenReviews(c *AuthenticationClient) *tokenReviews {
return &tokenReviews{
client: c,
}
}
func (c *tokenReviews) Create(obj *authentication.TokenReview) (result *authentication.TokenReview, err error) {
result = &authentication.TokenReview{}
err = c.client.Post().Resource("tokenreviews").Body(obj).Do().Into(result)
return
}