Merge pull request #59495 from ericchiang/client-auth-exec

Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.

 client-go: add an exec-based client auth provider

Updates https://github.com/kubernetes/features/issues/541
Implements https://github.com/kubernetes/community/pull/1503
Closes https://github.com/kubernetes/kubernetes/issues/57164

```release-note
client-go: alpha support for exec-based credential providers
```

/sig auth
/kind feature

Kubernetes-commit: cb9d6b51556a1677f262e35e4aded0051c424818
This commit is contained in:
Kubernetes Publisher 2018-02-28 22:03:16 -08:00
commit 6ec5f89077
28 changed files with 1511 additions and 239 deletions

304
Godeps/Godeps.json generated
View File

@ -152,115 +152,115 @@
},
{
"ImportPath": "k8s.io/api/admissionregistration/v1alpha1",
"Rev": "63d3b2501c8daf80fdac1051712fc3eb5e7fd351"
"Rev": "860727955743743199a0f053f2292f41d7196604"
},
{
"ImportPath": "k8s.io/api/admissionregistration/v1beta1",
"Rev": "63d3b2501c8daf80fdac1051712fc3eb5e7fd351"
"Rev": "860727955743743199a0f053f2292f41d7196604"
},
{
"ImportPath": "k8s.io/api/apps/v1",
"Rev": "63d3b2501c8daf80fdac1051712fc3eb5e7fd351"
"Rev": "860727955743743199a0f053f2292f41d7196604"
},
{
"ImportPath": "k8s.io/api/apps/v1beta1",
"Rev": "63d3b2501c8daf80fdac1051712fc3eb5e7fd351"
"Rev": "860727955743743199a0f053f2292f41d7196604"
},
{
"ImportPath": "k8s.io/api/apps/v1beta2",
"Rev": "63d3b2501c8daf80fdac1051712fc3eb5e7fd351"
"Rev": "860727955743743199a0f053f2292f41d7196604"
},
{
"ImportPath": "k8s.io/api/authentication/v1",
"Rev": "63d3b2501c8daf80fdac1051712fc3eb5e7fd351"
"Rev": "860727955743743199a0f053f2292f41d7196604"
},
{
"ImportPath": "k8s.io/api/authentication/v1beta1",
"Rev": "63d3b2501c8daf80fdac1051712fc3eb5e7fd351"
"Rev": "860727955743743199a0f053f2292f41d7196604"
},
{
"ImportPath": "k8s.io/api/authorization/v1",
"Rev": "63d3b2501c8daf80fdac1051712fc3eb5e7fd351"
"Rev": "860727955743743199a0f053f2292f41d7196604"
},
{
"ImportPath": "k8s.io/api/authorization/v1beta1",
"Rev": "63d3b2501c8daf80fdac1051712fc3eb5e7fd351"
"Rev": "860727955743743199a0f053f2292f41d7196604"
},
{
"ImportPath": "k8s.io/api/autoscaling/v1",
"Rev": "63d3b2501c8daf80fdac1051712fc3eb5e7fd351"
"Rev": "860727955743743199a0f053f2292f41d7196604"
},
{
"ImportPath": "k8s.io/api/autoscaling/v2beta1",
"Rev": "63d3b2501c8daf80fdac1051712fc3eb5e7fd351"
"Rev": "860727955743743199a0f053f2292f41d7196604"
},
{
"ImportPath": "k8s.io/api/batch/v1",
"Rev": "63d3b2501c8daf80fdac1051712fc3eb5e7fd351"
"Rev": "860727955743743199a0f053f2292f41d7196604"
},
{
"ImportPath": "k8s.io/api/batch/v1beta1",
"Rev": "63d3b2501c8daf80fdac1051712fc3eb5e7fd351"
"Rev": "860727955743743199a0f053f2292f41d7196604"
},
{
"ImportPath": "k8s.io/api/batch/v2alpha1",
"Rev": "63d3b2501c8daf80fdac1051712fc3eb5e7fd351"
"Rev": "860727955743743199a0f053f2292f41d7196604"
},
{
"ImportPath": "k8s.io/api/certificates/v1beta1",
"Rev": "63d3b2501c8daf80fdac1051712fc3eb5e7fd351"
"Rev": "860727955743743199a0f053f2292f41d7196604"
},
{
"ImportPath": "k8s.io/api/core/v1",
"Rev": "63d3b2501c8daf80fdac1051712fc3eb5e7fd351"
"Rev": "860727955743743199a0f053f2292f41d7196604"
},
{
"ImportPath": "k8s.io/api/events/v1beta1",
"Rev": "63d3b2501c8daf80fdac1051712fc3eb5e7fd351"
"Rev": "860727955743743199a0f053f2292f41d7196604"
},
{
"ImportPath": "k8s.io/api/extensions/v1beta1",
"Rev": "63d3b2501c8daf80fdac1051712fc3eb5e7fd351"
"Rev": "860727955743743199a0f053f2292f41d7196604"
},
{
"ImportPath": "k8s.io/api/networking/v1",
"Rev": "63d3b2501c8daf80fdac1051712fc3eb5e7fd351"
"Rev": "860727955743743199a0f053f2292f41d7196604"
},
{
"ImportPath": "k8s.io/api/policy/v1beta1",
"Rev": "63d3b2501c8daf80fdac1051712fc3eb5e7fd351"
"Rev": "860727955743743199a0f053f2292f41d7196604"
},
{
"ImportPath": "k8s.io/api/rbac/v1",
"Rev": "63d3b2501c8daf80fdac1051712fc3eb5e7fd351"
"Rev": "860727955743743199a0f053f2292f41d7196604"
},
{
"ImportPath": "k8s.io/api/rbac/v1alpha1",
"Rev": "63d3b2501c8daf80fdac1051712fc3eb5e7fd351"
"Rev": "860727955743743199a0f053f2292f41d7196604"
},
{
"ImportPath": "k8s.io/api/rbac/v1beta1",
"Rev": "63d3b2501c8daf80fdac1051712fc3eb5e7fd351"
"Rev": "860727955743743199a0f053f2292f41d7196604"
},
{
"ImportPath": "k8s.io/api/scheduling/v1alpha1",
"Rev": "63d3b2501c8daf80fdac1051712fc3eb5e7fd351"
"Rev": "860727955743743199a0f053f2292f41d7196604"
},
{
"ImportPath": "k8s.io/api/settings/v1alpha1",
"Rev": "63d3b2501c8daf80fdac1051712fc3eb5e7fd351"
"Rev": "860727955743743199a0f053f2292f41d7196604"
},
{
"ImportPath": "k8s.io/api/storage/v1",
"Rev": "63d3b2501c8daf80fdac1051712fc3eb5e7fd351"
"Rev": "860727955743743199a0f053f2292f41d7196604"
},
{
"ImportPath": "k8s.io/api/storage/v1alpha1",
"Rev": "63d3b2501c8daf80fdac1051712fc3eb5e7fd351"
"Rev": "860727955743743199a0f053f2292f41d7196604"
},
{
"ImportPath": "k8s.io/api/storage/v1beta1",
"Rev": "63d3b2501c8daf80fdac1051712fc3eb5e7fd351"
"Rev": "860727955743743199a0f053f2292f41d7196604"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/api/errors",
@ -428,475 +428,487 @@
},
{
"ImportPath": "k8s.io/client-go/discovery",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/discovery/fake",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/informers",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/informers/admissionregistration",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/informers/admissionregistration/v1alpha1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/informers/admissionregistration/v1beta1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/informers/apps",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/informers/apps/v1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/informers/apps/v1beta1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/informers/apps/v1beta2",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/informers/autoscaling",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/informers/autoscaling/v1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/informers/autoscaling/v2beta1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/informers/batch",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/informers/batch/v1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/informers/batch/v1beta1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/informers/batch/v2alpha1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/informers/certificates",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/informers/certificates/v1beta1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/informers/core",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/informers/core/v1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/informers/events",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/informers/events/v1beta1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/informers/extensions",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/informers/extensions/v1beta1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/informers/internalinterfaces",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/informers/networking",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/informers/networking/v1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/informers/policy",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/informers/policy/v1beta1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/informers/rbac",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/informers/rbac/v1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/informers/rbac/v1alpha1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/informers/rbac/v1beta1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/informers/scheduling",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/informers/scheduling/v1alpha1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/informers/settings",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/informers/settings/v1alpha1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/informers/storage",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/informers/storage/v1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/informers/storage/v1alpha1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/informers/storage/v1beta1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/kubernetes",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/scheme",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/admissionregistration/v1beta1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/apps/v1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/apps/v1beta1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/apps/v1beta2",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/authentication/v1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/authentication/v1beta1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/authorization/v1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/authorization/v1beta1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/autoscaling/v1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/batch/v1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/batch/v1beta1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/batch/v2alpha1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/certificates/v1beta1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/core/v1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/events/v1beta1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/extensions/v1beta1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/networking/v1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/policy/v1beta1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/rbac/v1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/rbac/v1alpha1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/rbac/v1beta1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/settings/v1alpha1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/storage/v1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/storage/v1alpha1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/storage/v1beta1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/listers/admissionregistration/v1alpha1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/listers/admissionregistration/v1beta1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/listers/apps/v1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/listers/apps/v1beta1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/listers/apps/v1beta2",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/listers/autoscaling/v1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/listers/autoscaling/v2beta1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/listers/batch/v1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/listers/batch/v1beta1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/listers/batch/v2alpha1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/listers/certificates/v1beta1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/listers/core/v1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/listers/events/v1beta1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/listers/extensions/v1beta1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/listers/networking/v1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/listers/policy/v1beta1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/listers/rbac/v1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/listers/rbac/v1alpha1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/listers/rbac/v1beta1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/listers/scheduling/v1alpha1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/listers/settings/v1alpha1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/listers/storage/v1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/listers/storage/v1alpha1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/listers/storage/v1beta1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/pkg/apis/clientauthentication",
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/pkg/apis/clientauthentication/v1alpha1",
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/pkg/version",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/plugin/pkg/client/auth/exec",
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/rest",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/rest/watch",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/testing",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/tools/auth",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/tools/cache",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/tools/clientcmd",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/tools/clientcmd/api",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/tools/clientcmd/api/latest",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/tools/clientcmd/api/v1",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/tools/metrics",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/tools/pager",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/tools/record",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/tools/reference",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/transport",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/util/buffer",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/util/cert",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/util/flowcontrol",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/util/homedir",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/util/integer",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/util/retry",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/client-go/util/workqueue",
"Rev": "dce0331f190bf5cc5352010093ab732fee8be96d"
"Rev": "2f45bcbf57f0cfde510a33e7d94a4c89955ff17b"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/util/proto",

2
Godeps/OWNERS generated
View File

@ -1,2 +1,4 @@
reviewers:
- dep-reviewers
approvers:
- dep-approvers

4
vendor/k8s.io/api/core/v1/types.go generated vendored
View File

@ -1021,8 +1021,8 @@ type FlockerVolumeSource struct {
type StorageMedium string
const (
StorageMediumDefault StorageMedium = "" // use whatever the default is for the node
StorageMediumMemory StorageMedium = "Memory" // use memory (tmpfs)
StorageMediumDefault StorageMedium = "" // use whatever the default is for the node, assume anything we don't explicitly handle is this
StorageMediumMemory StorageMedium = "Memory" // use memory (e.g. tmpfs on linux)
StorageMediumHugePages StorageMedium = "HugePages" // use hugepages
)

View File

@ -0,0 +1,36 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"doc.go",
"register.go",
"types.go",
"zz_generated.deepcopy.go",
],
importpath = "k8s.io/client-go/pkg/apis/clientauthentication",
visibility = ["//visibility:public"],
deps = [
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//staging/src/k8s.io/client-go/pkg/apis/clientauthentication/install:all-srcs",
"//staging/src/k8s.io/client-go/pkg/apis/clientauthentication/v1alpha1:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@ -0,0 +1,19 @@
/*
Copyright 2018 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.
*/
// +k8s:deepcopy-gen=package
// +groupName=client.authentication.k8s.io
package clientauthentication

View File

@ -0,0 +1,50 @@
/*
Copyright 2018 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 clientauthentication
import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
)
// GroupName is the group name use in this package
const GroupName = "client.authentication.k8s.io"
// SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal}
// Kind takes an unqualified kind and returns a Group qualified GroupKind
func Kind(kind string) schema.GroupKind {
return SchemeGroupVersion.WithKind(kind).GroupKind()
}
// Resource takes an unqualified resource and returns a Group qualified GroupResource
func Resource(resource string) schema.GroupResource {
return SchemeGroupVersion.WithResource(resource).GroupResource()
}
var (
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
AddToScheme = SchemeBuilder.AddToScheme
)
func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&ExecCredential{},
)
return nil
}

View File

@ -0,0 +1,70 @@
/*
Copyright 2018 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 clientauthentication
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// ExecCredentials is used by exec-based plugins to communicate credentials to
// HTTP transports.
type ExecCredential struct {
metav1.TypeMeta
// Spec holds information passed to the plugin by the transport. This contains
// request and runtime specific information, such as if the session is interactive.
Spec ExecCredentialSpec
// Status is filled in by the plugin and holds the credentials that the transport
// should use to contact the API.
// +optional
Status *ExecCredentialStatus
}
// ExecCredenitalSpec holds request and runtime specific information provided by
// the transport.
type ExecCredentialSpec struct {
// Response is populated when the transport encounters HTTP status codes, such as 401,
// suggesting previous credentials were invalid.
// +optional
Response *Response
// Interactive is true when the transport detects the command is being called from an
// interactive prompt.
// +optional
Interactive bool
}
// ExecCredentialStatus holds credentials for the transport to use.
type ExecCredentialStatus struct {
// ExpirationTimestamp indicates a time when the provided credentials expire.
// +optional
ExpirationTimestamp *metav1.Time
// Token is a bearer token used by the client for request authentication.
Token string
}
// Response defines metadata about a failed request, including HTTP status code and
// response headers.
type Response struct {
// Headers holds HTTP headers returned by the server.
Header map[string][]string
// Code is the HTTP status code returned by the server.
Code int32
}

View File

@ -0,0 +1,39 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"doc.go",
"register.go",
"types.go",
"zz_generated.conversion.go",
"zz_generated.deepcopy.go",
"zz_generated.defaults.go",
],
importpath = "k8s.io/client-go/pkg/apis/clientauthentication/v1alpha1",
deps = [
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/conversion:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/client-go/pkg/apis/clientauthentication:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)

View File

@ -0,0 +1,23 @@
/*
Copyright 2018 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.
*/
// +k8s:deepcopy-gen=package
// +k8s:conversion-gen=k8s.io/client-go/pkg/apis/clientauthentication
// +k8s:openapi-gen=true
// +k8s:defaulter-gen=TypeMeta
// +groupName=client.authentication.k8s.io
package v1alpha1

View File

@ -0,0 +1,55 @@
/*
Copyright 2018 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 v1alpha1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
)
// GroupName is the group name use in this package
const GroupName = "client.authentication.k8s.io"
// SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"}
// Resource takes an unqualified resource and returns a Group qualified GroupResource
func Resource(resource string) schema.GroupResource {
return SchemeGroupVersion.WithResource(resource).GroupResource()
}
var (
SchemeBuilder runtime.SchemeBuilder
localSchemeBuilder = &SchemeBuilder
AddToScheme = localSchemeBuilder.AddToScheme
)
func init() {
// We only register manually written functions here. The registration of the
// generated functions takes place in the generated files. The separation
// makes the code compile even when the generated files are missing.
localSchemeBuilder.Register(addKnownTypes)
}
func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&ExecCredential{},
)
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
return nil
}

View File

@ -0,0 +1,70 @@
/*
Copyright 2018 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 v1alpha1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// ExecCredentials is used by exec-based plugins to communicate credentials to
// HTTP transports.
type ExecCredential struct {
metav1.TypeMeta `json:",inline"`
// Spec holds information passed to the plugin by the transport. This contains
// request and runtime specific information, such as if the session is interactive.
Spec ExecCredentialSpec `json:"spec,omitempty"`
// Status is filled in by the plugin and holds the credentials that the transport
// should use to contact the API.
// +optional
Status *ExecCredentialStatus `json:"status,omitempty"`
}
// ExecCredenitalSpec holds request and runtime specific information provided by
// the transport.
type ExecCredentialSpec struct {
// Response is populated when the transport encounters HTTP status codes, such as 401,
// suggesting previous credentials were invalid.
// +optional
Response *Response `json:"response,omitempty"`
// Interactive is true when the transport detects the command is being called from an
// interactive prompt.
// +optional
Interactive bool `json:"interactive,omitempty"`
}
// ExecCredentialStatus holds credentials for the transport to use.
type ExecCredentialStatus struct {
// ExpirationTimestamp indicates a time when the provided credentials expire.
// +optional
ExpirationTimestamp *metav1.Time `json:"expirationTimestamp,omitempty"`
// Token is a bearer token used by the client for request authentication.
Token string `json:"token,omitempty"`
}
// Response defines metadata about a failed request, including HTTP status code and
// response headers.
type Response struct {
// Header holds HTTP headers returned by the server.
Header map[string][]string `json:"header,omitempty"`
// Code is the HTTP status code returned by the server.
Code int32 `json:"code,omitempty"`
}

View File

@ -0,0 +1,141 @@
// +build !ignore_autogenerated
/*
Copyright 2018 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.
*/
// Code generated by conversion-gen. DO NOT EDIT.
package v1alpha1
import (
unsafe "unsafe"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
conversion "k8s.io/apimachinery/pkg/conversion"
runtime "k8s.io/apimachinery/pkg/runtime"
clientauthentication "k8s.io/client-go/pkg/apis/clientauthentication"
)
func init() {
localSchemeBuilder.Register(RegisterConversions)
}
// RegisterConversions adds conversion functions to the given scheme.
// Public to allow building arbitrary schemes.
func RegisterConversions(scheme *runtime.Scheme) error {
return scheme.AddGeneratedConversionFuncs(
Convert_v1alpha1_ExecCredential_To_clientauthentication_ExecCredential,
Convert_clientauthentication_ExecCredential_To_v1alpha1_ExecCredential,
Convert_v1alpha1_ExecCredentialSpec_To_clientauthentication_ExecCredentialSpec,
Convert_clientauthentication_ExecCredentialSpec_To_v1alpha1_ExecCredentialSpec,
Convert_v1alpha1_ExecCredentialStatus_To_clientauthentication_ExecCredentialStatus,
Convert_clientauthentication_ExecCredentialStatus_To_v1alpha1_ExecCredentialStatus,
Convert_v1alpha1_Response_To_clientauthentication_Response,
Convert_clientauthentication_Response_To_v1alpha1_Response,
)
}
func autoConvert_v1alpha1_ExecCredential_To_clientauthentication_ExecCredential(in *ExecCredential, out *clientauthentication.ExecCredential, s conversion.Scope) error {
if err := Convert_v1alpha1_ExecCredentialSpec_To_clientauthentication_ExecCredentialSpec(&in.Spec, &out.Spec, s); err != nil {
return err
}
out.Status = (*clientauthentication.ExecCredentialStatus)(unsafe.Pointer(in.Status))
return nil
}
// Convert_v1alpha1_ExecCredential_To_clientauthentication_ExecCredential is an autogenerated conversion function.
func Convert_v1alpha1_ExecCredential_To_clientauthentication_ExecCredential(in *ExecCredential, out *clientauthentication.ExecCredential, s conversion.Scope) error {
return autoConvert_v1alpha1_ExecCredential_To_clientauthentication_ExecCredential(in, out, s)
}
func autoConvert_clientauthentication_ExecCredential_To_v1alpha1_ExecCredential(in *clientauthentication.ExecCredential, out *ExecCredential, s conversion.Scope) error {
if err := Convert_clientauthentication_ExecCredentialSpec_To_v1alpha1_ExecCredentialSpec(&in.Spec, &out.Spec, s); err != nil {
return err
}
out.Status = (*ExecCredentialStatus)(unsafe.Pointer(in.Status))
return nil
}
// Convert_clientauthentication_ExecCredential_To_v1alpha1_ExecCredential is an autogenerated conversion function.
func Convert_clientauthentication_ExecCredential_To_v1alpha1_ExecCredential(in *clientauthentication.ExecCredential, out *ExecCredential, s conversion.Scope) error {
return autoConvert_clientauthentication_ExecCredential_To_v1alpha1_ExecCredential(in, out, s)
}
func autoConvert_v1alpha1_ExecCredentialSpec_To_clientauthentication_ExecCredentialSpec(in *ExecCredentialSpec, out *clientauthentication.ExecCredentialSpec, s conversion.Scope) error {
out.Response = (*clientauthentication.Response)(unsafe.Pointer(in.Response))
out.Interactive = in.Interactive
return nil
}
// Convert_v1alpha1_ExecCredentialSpec_To_clientauthentication_ExecCredentialSpec is an autogenerated conversion function.
func Convert_v1alpha1_ExecCredentialSpec_To_clientauthentication_ExecCredentialSpec(in *ExecCredentialSpec, out *clientauthentication.ExecCredentialSpec, s conversion.Scope) error {
return autoConvert_v1alpha1_ExecCredentialSpec_To_clientauthentication_ExecCredentialSpec(in, out, s)
}
func autoConvert_clientauthentication_ExecCredentialSpec_To_v1alpha1_ExecCredentialSpec(in *clientauthentication.ExecCredentialSpec, out *ExecCredentialSpec, s conversion.Scope) error {
out.Response = (*Response)(unsafe.Pointer(in.Response))
out.Interactive = in.Interactive
return nil
}
// Convert_clientauthentication_ExecCredentialSpec_To_v1alpha1_ExecCredentialSpec is an autogenerated conversion function.
func Convert_clientauthentication_ExecCredentialSpec_To_v1alpha1_ExecCredentialSpec(in *clientauthentication.ExecCredentialSpec, out *ExecCredentialSpec, s conversion.Scope) error {
return autoConvert_clientauthentication_ExecCredentialSpec_To_v1alpha1_ExecCredentialSpec(in, out, s)
}
func autoConvert_v1alpha1_ExecCredentialStatus_To_clientauthentication_ExecCredentialStatus(in *ExecCredentialStatus, out *clientauthentication.ExecCredentialStatus, s conversion.Scope) error {
out.ExpirationTimestamp = (*v1.Time)(unsafe.Pointer(in.ExpirationTimestamp))
out.Token = in.Token
return nil
}
// Convert_v1alpha1_ExecCredentialStatus_To_clientauthentication_ExecCredentialStatus is an autogenerated conversion function.
func Convert_v1alpha1_ExecCredentialStatus_To_clientauthentication_ExecCredentialStatus(in *ExecCredentialStatus, out *clientauthentication.ExecCredentialStatus, s conversion.Scope) error {
return autoConvert_v1alpha1_ExecCredentialStatus_To_clientauthentication_ExecCredentialStatus(in, out, s)
}
func autoConvert_clientauthentication_ExecCredentialStatus_To_v1alpha1_ExecCredentialStatus(in *clientauthentication.ExecCredentialStatus, out *ExecCredentialStatus, s conversion.Scope) error {
out.ExpirationTimestamp = (*v1.Time)(unsafe.Pointer(in.ExpirationTimestamp))
out.Token = in.Token
return nil
}
// Convert_clientauthentication_ExecCredentialStatus_To_v1alpha1_ExecCredentialStatus is an autogenerated conversion function.
func Convert_clientauthentication_ExecCredentialStatus_To_v1alpha1_ExecCredentialStatus(in *clientauthentication.ExecCredentialStatus, out *ExecCredentialStatus, s conversion.Scope) error {
return autoConvert_clientauthentication_ExecCredentialStatus_To_v1alpha1_ExecCredentialStatus(in, out, s)
}
func autoConvert_v1alpha1_Response_To_clientauthentication_Response(in *Response, out *clientauthentication.Response, s conversion.Scope) error {
out.Header = *(*map[string][]string)(unsafe.Pointer(&in.Header))
out.Code = in.Code
return nil
}
// Convert_v1alpha1_Response_To_clientauthentication_Response is an autogenerated conversion function.
func Convert_v1alpha1_Response_To_clientauthentication_Response(in *Response, out *clientauthentication.Response, s conversion.Scope) error {
return autoConvert_v1alpha1_Response_To_clientauthentication_Response(in, out, s)
}
func autoConvert_clientauthentication_Response_To_v1alpha1_Response(in *clientauthentication.Response, out *Response, s conversion.Scope) error {
out.Header = *(*map[string][]string)(unsafe.Pointer(&in.Header))
out.Code = in.Code
return nil
}
// Convert_clientauthentication_Response_To_v1alpha1_Response is an autogenerated conversion function.
func Convert_clientauthentication_Response_To_v1alpha1_Response(in *clientauthentication.Response, out *Response, s conversion.Scope) error {
return autoConvert_clientauthentication_Response_To_v1alpha1_Response(in, out, s)
}

View File

@ -0,0 +1,137 @@
// +build !ignore_autogenerated
/*
Copyright 2018 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.
*/
// Code generated by deepcopy-gen. DO NOT EDIT.
package v1alpha1
import (
runtime "k8s.io/apimachinery/pkg/runtime"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ExecCredential) DeepCopyInto(out *ExecCredential) {
*out = *in
out.TypeMeta = in.TypeMeta
in.Spec.DeepCopyInto(&out.Spec)
if in.Status != nil {
in, out := &in.Status, &out.Status
if *in == nil {
*out = nil
} else {
*out = new(ExecCredentialStatus)
(*in).DeepCopyInto(*out)
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExecCredential.
func (in *ExecCredential) DeepCopy() *ExecCredential {
if in == nil {
return nil
}
out := new(ExecCredential)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *ExecCredential) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ExecCredentialSpec) DeepCopyInto(out *ExecCredentialSpec) {
*out = *in
if in.Response != nil {
in, out := &in.Response, &out.Response
if *in == nil {
*out = nil
} else {
*out = new(Response)
(*in).DeepCopyInto(*out)
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExecCredentialSpec.
func (in *ExecCredentialSpec) DeepCopy() *ExecCredentialSpec {
if in == nil {
return nil
}
out := new(ExecCredentialSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ExecCredentialStatus) DeepCopyInto(out *ExecCredentialStatus) {
*out = *in
if in.ExpirationTimestamp != nil {
in, out := &in.ExpirationTimestamp, &out.ExpirationTimestamp
if *in == nil {
*out = nil
} else {
*out = (*in).DeepCopy()
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExecCredentialStatus.
func (in *ExecCredentialStatus) DeepCopy() *ExecCredentialStatus {
if in == nil {
return nil
}
out := new(ExecCredentialStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Response) DeepCopyInto(out *Response) {
*out = *in
if in.Header != nil {
in, out := &in.Header, &out.Header
*out = make(map[string][]string, len(*in))
for key, val := range *in {
if val == nil {
(*out)[key] = nil
} else {
(*out)[key] = make([]string, len(val))
copy((*out)[key], val)
}
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Response.
func (in *Response) DeepCopy() *Response {
if in == nil {
return nil
}
out := new(Response)
in.DeepCopyInto(out)
return out
}

View File

@ -0,0 +1,32 @@
// +build !ignore_autogenerated
/*
Copyright 2018 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.
*/
// Code generated by defaulter-gen. DO NOT EDIT.
package v1alpha1
import (
runtime "k8s.io/apimachinery/pkg/runtime"
)
// RegisterDefaults adds defaulters functions to the given scheme.
// Public to allow building arbitrary schemes.
// All generated defaulters are covering - they call all nested defaulters.
func RegisterDefaults(scheme *runtime.Scheme) error {
return nil
}

View File

@ -0,0 +1,137 @@
// +build !ignore_autogenerated
/*
Copyright 2018 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.
*/
// Code generated by deepcopy-gen. DO NOT EDIT.
package clientauthentication
import (
runtime "k8s.io/apimachinery/pkg/runtime"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ExecCredential) DeepCopyInto(out *ExecCredential) {
*out = *in
out.TypeMeta = in.TypeMeta
in.Spec.DeepCopyInto(&out.Spec)
if in.Status != nil {
in, out := &in.Status, &out.Status
if *in == nil {
*out = nil
} else {
*out = new(ExecCredentialStatus)
(*in).DeepCopyInto(*out)
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExecCredential.
func (in *ExecCredential) DeepCopy() *ExecCredential {
if in == nil {
return nil
}
out := new(ExecCredential)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *ExecCredential) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ExecCredentialSpec) DeepCopyInto(out *ExecCredentialSpec) {
*out = *in
if in.Response != nil {
in, out := &in.Response, &out.Response
if *in == nil {
*out = nil
} else {
*out = new(Response)
(*in).DeepCopyInto(*out)
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExecCredentialSpec.
func (in *ExecCredentialSpec) DeepCopy() *ExecCredentialSpec {
if in == nil {
return nil
}
out := new(ExecCredentialSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ExecCredentialStatus) DeepCopyInto(out *ExecCredentialStatus) {
*out = *in
if in.ExpirationTimestamp != nil {
in, out := &in.ExpirationTimestamp, &out.ExpirationTimestamp
if *in == nil {
*out = nil
} else {
*out = (*in).DeepCopy()
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExecCredentialStatus.
func (in *ExecCredentialStatus) DeepCopy() *ExecCredentialStatus {
if in == nil {
return nil
}
out := new(ExecCredentialStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Response) DeepCopyInto(out *Response) {
*out = *in
if in.Header != nil {
in, out := &in.Header, &out.Header
*out = make(map[string][]string, len(*in))
for key, val := range *in {
if val == nil {
(*out)[key] = nil
} else {
(*out)[key] = make([]string, len(val))
copy((*out)[key], val)
}
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Response.
func (in *Response) DeepCopy() *Response {
if in == nil {
return nil
}
out := new(Response)
in.DeepCopyInto(out)
return out
}

View File

@ -0,0 +1,44 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
srcs = ["exec.go"],
importpath = "k8s.io/client-go/plugin/pkg/client/auth/exec",
visibility = ["//visibility:public"],
deps = [
"//vendor/github.com/golang/glog:go_default_library",
"//vendor/golang.org/x/crypto/ssh/terminal:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
"//vendor/k8s.io/client-go/pkg/apis/clientauthentication:go_default_library",
"//vendor/k8s.io/client-go/pkg/apis/clientauthentication/v1alpha1:go_default_library",
"//vendor/k8s.io/client-go/tools/clientcmd/api:go_default_library",
],
)
go_test(
name = "go_default_test",
srcs = ["exec_test.go"],
data = glob(["testdata/**"]),
embed = [":go_default_library"],
deps = [
"//vendor/k8s.io/client-go/pkg/apis/clientauthentication:go_default_library",
"//vendor/k8s.io/client-go/tools/clientcmd/api:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@ -0,0 +1,280 @@
/*
Copyright 2018 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 exec
import (
"bytes"
"fmt"
"io"
"net/http"
"os"
"os/exec"
"sync"
"time"
"github.com/golang/glog"
"golang.org/x/crypto/ssh/terminal"
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/client-go/pkg/apis/clientauthentication"
"k8s.io/client-go/pkg/apis/clientauthentication/v1alpha1"
"k8s.io/client-go/tools/clientcmd/api"
)
const execInfoEnv = "KUBERNETES_EXEC_INFO"
var scheme = runtime.NewScheme()
var codecs = serializer.NewCodecFactory(scheme)
func init() {
v1.AddToGroupVersion(scheme, schema.GroupVersion{Version: "v1"})
v1alpha1.AddToScheme(scheme)
clientauthentication.AddToScheme(scheme)
}
var (
// Since transports can be constantly re-initialized by programs like kubectl,
// keep a cache of initialized authenticators keyed by a hash of their config.
globalCache = newCache()
// The list of API versions we accept.
apiVersions = map[string]schema.GroupVersion{
v1alpha1.SchemeGroupVersion.String(): v1alpha1.SchemeGroupVersion,
}
)
func newCache() *cache {
return &cache{m: make(map[string]*Authenticator)}
}
func cacheKey(c *api.ExecConfig) string {
return fmt.Sprintf("%#v", c)
}
type cache struct {
mu sync.Mutex
m map[string]*Authenticator
}
func (c *cache) get(s string) (*Authenticator, bool) {
c.mu.Lock()
defer c.mu.Unlock()
a, ok := c.m[s]
return a, ok
}
// put inserts an authenticator into the cache. If an authenticator is already
// associated with the key, the first one is returned instead.
func (c *cache) put(s string, a *Authenticator) *Authenticator {
c.mu.Lock()
defer c.mu.Unlock()
existing, ok := c.m[s]
if ok {
return existing
}
c.m[s] = a
return a
}
// GetAuthenticator returns an exec-based plugin for providing client credentials.
func GetAuthenticator(config *api.ExecConfig) (*Authenticator, error) {
return newAuthenticator(globalCache, config)
}
func newAuthenticator(c *cache, config *api.ExecConfig) (*Authenticator, error) {
key := cacheKey(config)
if a, ok := c.get(key); ok {
return a, nil
}
gv, ok := apiVersions[config.APIVersion]
if !ok {
return nil, fmt.Errorf("exec plugin: invalid apiVersion %q", config.APIVersion)
}
a := &Authenticator{
cmd: config.Command,
args: config.Args,
group: gv,
stdin: os.Stdin,
stderr: os.Stderr,
interactive: terminal.IsTerminal(int(os.Stdout.Fd())),
now: time.Now,
environ: os.Environ,
}
for _, env := range config.Env {
a.env = append(a.env, env.Name+"="+env.Value)
}
return c.put(key, a), nil
}
// Authenticator is a client credential provider that rotates credentials by executing a plugin.
// The plugin input and output are defined by the API group client.authentication.k8s.io.
type Authenticator struct {
// Set by the config
cmd string
args []string
group schema.GroupVersion
env []string
// Stubbable for testing
stdin io.Reader
stderr io.Writer
interactive bool
now func() time.Time
environ func() []string
// Cached results.
//
// The mutex also guards calling the plugin. Since the plugin could be
// interactive we want to make sure it's only called once.
mu sync.Mutex
cachedToken string
exp time.Time
}
// WrapTransport instruments an existing http.RoundTripper with credentials returned
// by the plugin.
func (a *Authenticator) WrapTransport(rt http.RoundTripper) http.RoundTripper {
return &roundTripper{a, rt}
}
type roundTripper struct {
a *Authenticator
base http.RoundTripper
}
func (r *roundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
// If a user has already set credentials, use that. This makes commands like
// "kubectl get --token (token) pods" work.
if req.Header.Get("Authorization") != "" {
return r.base.RoundTrip(req)
}
token, err := r.a.token()
if err != nil {
return nil, fmt.Errorf("getting token: %v", err)
}
req.Header.Set("Authorization", "Bearer "+token)
res, err := r.base.RoundTrip(req)
if err != nil {
return nil, err
}
if res.StatusCode == http.StatusUnauthorized {
resp := &clientauthentication.Response{
Header: res.Header,
Code: int32(res.StatusCode),
}
if err := r.a.refresh(token, resp); err != nil {
glog.Errorf("refreshing token: %v", err)
}
}
return res, nil
}
func (a *Authenticator) tokenExpired() bool {
if a.exp.IsZero() {
return false
}
return a.now().After(a.exp)
}
func (a *Authenticator) token() (string, error) {
a.mu.Lock()
defer a.mu.Unlock()
if a.cachedToken != "" && !a.tokenExpired() {
return a.cachedToken, nil
}
return a.getToken(nil)
}
// refresh executes the plugin to force a rotation of the token.
func (a *Authenticator) refresh(token string, r *clientauthentication.Response) error {
a.mu.Lock()
defer a.mu.Unlock()
if token != a.cachedToken {
// Token already rotated.
return nil
}
_, err := a.getToken(r)
return err
}
// getToken executes the plugin and reads the credentials from stdout. It must be
// called while holding the Authenticator's mutex.
func (a *Authenticator) getToken(r *clientauthentication.Response) (string, error) {
cred := &clientauthentication.ExecCredential{
Spec: clientauthentication.ExecCredentialSpec{
Response: r,
Interactive: a.interactive,
},
}
data, err := runtime.Encode(codecs.LegacyCodec(a.group), cred)
if err != nil {
return "", fmt.Errorf("encode ExecCredentials: %v", err)
}
env := append(a.environ(), a.env...)
env = append(env, fmt.Sprintf("%s=%s", execInfoEnv, data))
stdout := &bytes.Buffer{}
cmd := exec.Command(a.cmd, a.args...)
cmd.Env = env
cmd.Stderr = a.stderr
cmd.Stdout = stdout
if a.interactive {
cmd.Stdin = a.stdin
}
if err := cmd.Run(); err != nil {
return "", fmt.Errorf("exec: %v", err)
}
_, gvk, err := codecs.UniversalDecoder(a.group).Decode(stdout.Bytes(), nil, cred)
if err != nil {
return "", fmt.Errorf("decode stdout: %v", err)
}
if gvk.Group != a.group.Group || gvk.Version != a.group.Version {
return "", fmt.Errorf("exec plugin is configured to use API version %s, plugin returned version %s",
a.group, schema.GroupVersion{Group: gvk.Group, Version: gvk.Version})
}
if cred.Status == nil {
return "", fmt.Errorf("exec plugin didn't return a status field")
}
if cred.Status.Token == "" {
return "", fmt.Errorf("exec plugin didn't return a token")
}
if cred.Status.ExpirationTimestamp != nil {
a.exp = cred.Status.ExpirationTimestamp.Time
} else {
a.exp = time.Time{}
}
a.cachedToken = cred.Status.Token
return a.cachedToken, nil
}

2
vendor/k8s.io/client-go/rest/BUILD generated vendored
View File

@ -54,7 +54,6 @@ go_library(
"transport.go",
"url_utils.go",
"urlbackoff.go",
"versions.go",
"zz_generated.deepcopy.go",
],
importpath = "k8s.io/client-go/rest",
@ -72,6 +71,7 @@ go_library(
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/watch:go_default_library",
"//vendor/k8s.io/client-go/pkg/version:go_default_library",
"//vendor/k8s.io/client-go/plugin/pkg/client/auth/exec:go_default_library",
"//vendor/k8s.io/client-go/rest/watch:go_default_library",
"//vendor/k8s.io/client-go/tools/clientcmd/api:go_default_library",
"//vendor/k8s.io/client-go/tools/metrics:go_default_library",

View File

@ -77,6 +77,9 @@ type Config struct {
// Callback to persist config for AuthProvider.
AuthConfigPersister AuthProviderConfigPersister
// Exec-based authentication provider.
ExecProvider *clientcmdapi.ExecConfig
// TLSClientConfig contains settings to enable transport layer security
TLSClientConfig
@ -432,6 +435,7 @@ func CopyConfig(config *Config) *Config {
},
AuthProvider: config.AuthProvider,
AuthConfigPersister: config.AuthConfigPersister,
ExecProvider: config.ExecProvider,
TLSClientConfig: TLSClientConfig{
Insecure: config.TLSClientConfig.Insecure,
ServerName: config.TLSClientConfig.ServerName,

View File

@ -20,6 +20,7 @@ import (
"crypto/tls"
"net/http"
"k8s.io/client-go/plugin/pkg/client/auth/exec"
"k8s.io/client-go/transport"
)
@ -59,6 +60,20 @@ func HTTPWrappersForConfig(config *Config, rt http.RoundTripper) (http.RoundTrip
// TransportConfig converts a client config to an appropriate transport config.
func (c *Config) TransportConfig() (*transport.Config, error) {
wt := c.WrapTransport
if c.ExecProvider != nil {
provider, err := exec.GetAuthenticator(c.ExecProvider)
if err != nil {
return nil, err
}
if wt != nil {
previousWT := wt
wt = func(rt http.RoundTripper) http.RoundTripper {
return provider.WrapTransport(previousWT(rt))
}
} else {
wt = provider.WrapTransport
}
}
if c.AuthProvider != nil {
provider, err := GetAuthProvider(c.Host, c.AuthProvider, c.AuthConfigPersister)
if err != nil {

View File

@ -1,88 +0,0 @@
/*
Copyright 2014 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package rest
import (
"encoding/json"
"fmt"
"net/http"
"path"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
const (
legacyAPIPath = "/api"
defaultAPIPath = "/apis"
)
// TODO: Is this obsoleted by the discovery client?
// ServerAPIVersions returns the GroupVersions supported by the API server.
// It creates a RESTClient based on the passed in config, but it doesn't rely
// on the Version and Codec of the config, because it uses AbsPath and
// takes the raw response.
func ServerAPIVersions(c *Config) (groupVersions []string, err error) {
transport, err := TransportFor(c)
if err != nil {
return nil, err
}
client := http.Client{Transport: transport}
configCopy := *c
configCopy.GroupVersion = nil
configCopy.APIPath = ""
baseURL, _, err := defaultServerUrlFor(&configCopy)
if err != nil {
return nil, err
}
// Get the groupVersions exposed at /api
originalPath := baseURL.Path
baseURL.Path = path.Join(originalPath, legacyAPIPath)
resp, err := client.Get(baseURL.String())
if err != nil {
return nil, err
}
var v metav1.APIVersions
defer resp.Body.Close()
err = json.NewDecoder(resp.Body).Decode(&v)
if err != nil {
return nil, fmt.Errorf("unexpected error: %v", err)
}
groupVersions = append(groupVersions, v.Versions...)
// Get the groupVersions exposed at /apis
baseURL.Path = path.Join(originalPath, defaultAPIPath)
resp2, err := client.Get(baseURL.String())
if err != nil {
return nil, err
}
var apiGroupList metav1.APIGroupList
defer resp2.Body.Close()
err = json.NewDecoder(resp2.Body).Decode(&apiGroupList)
if err != nil {
return nil, fmt.Errorf("unexpected error: %v", err)
}
for _, g := range apiGroupList.Groups {
for _, gv := range g.Versions {
groupVersions = append(groupVersions, gv.GroupVersion)
}
}
return groupVersions, nil
}

View File

@ -119,6 +119,9 @@ type AuthInfo struct {
// AuthProvider specifies a custom authentication plugin for the kubernetes cluster.
// +optional
AuthProvider *AuthProviderConfig `json:"auth-provider,omitempty"`
// Exec specifies a custom exec-based authentication plugin for the kubernetes cluster.
// +optional
Exec *ExecConfig `json:"exec,omitempty"`
// Extensions holds additional information. This is useful for extenders so that reads and writes don't clobber unknown fields
// +optional
Extensions map[string]runtime.Object `json:"extensions,omitempty"`
@ -147,6 +150,35 @@ type AuthProviderConfig struct {
Config map[string]string `json:"config,omitempty"`
}
// ExecConfig specifies a command to provide client credentials. The command is exec'd
// and outputs structured stdout holding credentials.
//
// See the client.authentiction.k8s.io API group for specifications of the exact input
// and output format
type ExecConfig struct {
// Command to execute.
Command string `json:"command"`
// Arguments to pass to the command when executing it.
// +optional
Args []string `json:"args"`
// Env defines additional environment variables to expose to the process. These
// are unioned with the host's environment, as well as variables client-go uses
// to pass argument to the plugin.
// +optional
Env []ExecEnvVar `json:"env"`
// Preferred input version of the ExecInfo. The returned ExecCredentials MUST use
// the same encoding version as the input.
APIVersion string `json:"apiVersion,omitempty"`
}
// ExecEnvVar is used for setting environment variables when executing an exec-based
// credential plugin.
type ExecEnvVar struct {
Name string `json:"name"`
Value string `json:"value"`
}
// NewConfig is a convenience function that returns a new Config object with non-nil maps
func NewConfig() *Config {
return &Config{

View File

@ -113,6 +113,9 @@ type AuthInfo struct {
// AuthProvider specifies a custom authentication plugin for the kubernetes cluster.
// +optional
AuthProvider *AuthProviderConfig `json:"auth-provider,omitempty"`
// Exec specifies a custom exec-based authentication plugin for the kubernetes cluster.
// +optional
Exec *ExecConfig `json:"exec,omitempty"`
// Extensions holds additional information. This is useful for extenders so that reads and writes don't clobber unknown fields
// +optional
Extensions []NamedExtension `json:"extensions,omitempty"`
@ -169,3 +172,32 @@ type AuthProviderConfig struct {
Name string `json:"name"`
Config map[string]string `json:"config"`
}
// ExecConfig specifies a command to provide client credentials. The command is exec'd
// and outputs structured stdout holding credentials.
//
// See the client.authentiction.k8s.io API group for specifications of the exact input
// and output format
type ExecConfig struct {
// Command to execute.
Command string `json:"command"`
// Arguments to pass to the command when executing it.
// +optional
Args []string `json:"args"`
// Env defines additional environment variables to expose to the process. These
// are unioned with the host's environment, as well as variables client-go uses
// to pass argument to the plugin.
// +optional
Env []ExecEnvVar `json:"env"`
// Preferred input version of the ExecInfo. The returned ExecCredentials MUST use
// the same encoding version as the input.
APIVersion string `json:"apiVersion,omitempty"`
}
// ExecEnvVar is used for setting environment variables when executing an exec-based
// credential plugin.
type ExecEnvVar struct {
Name string `json:"name"`
Value string `json:"value"`
}

View File

@ -63,6 +63,15 @@ func (in *AuthInfo) DeepCopyInto(out *AuthInfo) {
(*in).DeepCopyInto(*out)
}
}
if in.Exec != nil {
in, out := &in.Exec, &out.Exec
if *in == nil {
*out = nil
} else {
*out = new(ExecConfig)
(*in).DeepCopyInto(*out)
}
}
if in.Extensions != nil {
in, out := &in.Extensions, &out.Extensions
*out = make([]NamedExtension, len(*in))
@ -210,6 +219,48 @@ func (in *Context) DeepCopy() *Context {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ExecConfig) DeepCopyInto(out *ExecConfig) {
*out = *in
if in.Args != nil {
in, out := &in.Args, &out.Args
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.Env != nil {
in, out := &in.Env, &out.Env
*out = make([]ExecEnvVar, len(*in))
copy(*out, *in)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExecConfig.
func (in *ExecConfig) DeepCopy() *ExecConfig {
if in == nil {
return nil
}
out := new(ExecConfig)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ExecEnvVar) DeepCopyInto(out *ExecEnvVar) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExecEnvVar.
func (in *ExecEnvVar) DeepCopy() *ExecEnvVar {
if in == nil {
return nil
}
out := new(ExecEnvVar)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *NamedAuthInfo) DeepCopyInto(out *NamedAuthInfo) {
*out = *in

View File

@ -63,6 +63,15 @@ func (in *AuthInfo) DeepCopyInto(out *AuthInfo) {
(*in).DeepCopyInto(*out)
}
}
if in.Exec != nil {
in, out := &in.Exec, &out.Exec
if *in == nil {
*out = nil
} else {
*out = new(ExecConfig)
(*in).DeepCopyInto(*out)
}
}
if in.Extensions != nil {
in, out := &in.Extensions, &out.Extensions
*out = make(map[string]runtime.Object, len(*in))
@ -241,6 +250,48 @@ func (in *Context) DeepCopy() *Context {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ExecConfig) DeepCopyInto(out *ExecConfig) {
*out = *in
if in.Args != nil {
in, out := &in.Args, &out.Args
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.Env != nil {
in, out := &in.Env, &out.Env
*out = make([]ExecEnvVar, len(*in))
copy(*out, *in)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExecConfig.
func (in *ExecConfig) DeepCopy() *ExecConfig {
if in == nil {
return nil
}
out := new(ExecConfig)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ExecEnvVar) DeepCopyInto(out *ExecEnvVar) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExecEnvVar.
func (in *ExecEnvVar) DeepCopy() *ExecEnvVar {
if in == nil {
return nil
}
out := new(ExecEnvVar)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Preferences) DeepCopyInto(out *Preferences) {
*out = *in

View File

@ -241,6 +241,9 @@ func (config *DirectClientConfig) getUserIdentificationPartialConfig(configAuthI
mergedConfig.AuthProvider = configAuthInfo.AuthProvider
mergedConfig.AuthConfigPersister = persistAuthConfig
}
if configAuthInfo.Exec != nil {
mergedConfig.ExecProvider = configAuthInfo.Exec
}
// if there still isn't enough information to authenticate the user, try prompting
if !canIdentifyUser(*mergedConfig) && (fallbackReader != nil) {
@ -291,7 +294,8 @@ func canIdentifyUser(config restclient.Config) bool {
return len(config.Username) > 0 ||
(len(config.CertFile) > 0 || len(config.CertData) > 0) ||
len(config.BearerToken) > 0 ||
config.AuthProvider != nil
config.AuthProvider != nil ||
config.ExecProvider != nil
}
// Namespace implements ClientConfig

View File

@ -557,7 +557,12 @@ func GetClusterFileReferences(cluster *clientcmdapi.Cluster) []*string {
}
func GetAuthInfoFileReferences(authInfo *clientcmdapi.AuthInfo) []*string {
return []*string{&authInfo.ClientCertificate, &authInfo.ClientKey, &authInfo.TokenFile}
s := []*string{&authInfo.ClientCertificate, &authInfo.ClientKey, &authInfo.TokenFile}
// Only resolve exec command if it isn't PATH based.
if authInfo.Exec != nil && strings.ContainsRune(authInfo.Exec.Command, filepath.Separator) {
s = append(s, &authInfo.Exec.Command)
}
return s
}
// ResolvePaths updates the given refs to be absolute paths, relative to the given base directory

View File

@ -237,6 +237,25 @@ func validateAuthInfo(authInfoName string, authInfo clientcmdapi.AuthInfo) []err
}
}
if authInfo.Exec != nil {
if authInfo.AuthProvider != nil {
validationErrors = append(validationErrors, fmt.Errorf("authProvider cannot be provided in combination with an exec plugin for %s", authInfoName))
}
if len(authInfo.Exec.Command) == 0 {
validationErrors = append(validationErrors, fmt.Errorf("command must be specified for %v to use exec authentication plugin", authInfoName))
}
if len(authInfo.Exec.APIVersion) == 0 {
validationErrors = append(validationErrors, fmt.Errorf("apiVersion must be specified for %v to use exec authentication plugin", authInfoName))
}
for _, v := range authInfo.Exec.Env {
if len(v.Name) == 0 {
validationErrors = append(validationErrors, fmt.Errorf("env variable name must be specified for %v to use exec authentication plugin", authInfoName))
} else if len(v.Value) == 0 {
validationErrors = append(validationErrors, fmt.Errorf("env variable %s value must be specified for %v to use exec authentication plugin", v.Name, authInfoName))
}
}
}
// authPath also provides information for the client to identify the server, so allow multiple auth methods in that case
if (len(methods) > 1) && (!usingAuthPath) {
validationErrors = append(validationErrors, fmt.Errorf("more than one authentication method found for %v; found %v, only one is allowed", authInfoName, methods))