Compare commits

..

37 Commits

Author SHA1 Message Date
Kubernetes Publisher
9e4461f622 Fix Godeps.json to point to kubernetes-1.11.4-beta.0 tags 2018-09-10 06:28:10 +00:00
Kubernetes Publisher
f2f85107ca Merge pull request #67164 from dekkagaijin/automated-cherry-pick-of-#65799-upstream-release-1.11
Automatic merge from submit-queue.

Automated cherry pick of #65799: Escape illegal characters in remote extra keys

Cherry pick of #65799 on release-1.11.

#65799: Escape illegal characters in remote extra keys

```release-note
action required: the API server and client-go libraries have been fixed to support additional non-alpha-numeric characters in UserInfo "extra" data keys. Both should be updated in order to properly support extra data containing "/" characters or other characters disallowed in HTTP headers.
```

Kubernetes-commit: f53fc73da201d21cb12f6093a68f01b5ef594e5c
2018-08-21 07:40:22 +00:00
Kubernetes Publisher
60fd738f89 Merge pull request #67240 from nikhita/automated-cherry-pick-of-#66249-upstream-release-1.11
Automatic merge from submit-queue.

Automated cherry pick of #66249: fill in normal restmapping info with the legacy guess

Fixes 1.11 part of https://github.com/kubernetes/kubernetes/issues/67235

Cherry pick of #66249 on release-1.11.

#66249: fill in normal restmapping info with the legacy guess

```release-note
Fix creation of custom resources when the CRD contains non-conventional pluralization and subresources
```

Kubernetes-commit: 10ecc6db83fd47a93eb0940e2e4434f2b0a5c3ec
2018-08-15 03:28:43 -07:00
Kubernetes Publisher
1f13a808da Merge pull request #66683 from awly/automated-cherry-pick-of-#66395-upstream-release-1.11
Automatic merge from submit-queue.

Automated cherry pick of #66395: Set connrotation dialer via restclient.Config.Dialer

Cherry pick of #66395 on release-1.11.

#66395: Set connrotation dialer via restclient.Config.Dialer

Kubernetes-commit: 77555257773c21d18a2eafa3c532b28973970d3b
2018-08-06 13:40:42 +00:00
Andrew Lytvynov
401c87eddd Set connrotation dialer via restclient.Config.Dialer
Instead of Transport. This fixes ExecPlugin, which fails if
restclient.Config.Transport is set.

Kubernetes-commit: 89322ec5deb057483b3c91816aac48fe7044ecd8
2018-07-25 16:22:32 -07:00
David Eads
897ec2f639 fill in normal restmapping info with the legacy guess
Kubernetes-commit: 4d6d243503535ea290530d5548ac657b1529986f
2018-07-16 13:38:43 -04:00
Jake Sanders
e07adc6e69 Escape illegal characters in remote extra keys
Signed-off-by: Jake Sanders <jsand@google.com>

Kubernetes-commit: 1db56879e5386ea8baee0f658eed40bc7658b24d
2018-07-03 21:19:15 -07:00
Kubernetes Publisher
e5bc2a7bbb Merge pull request #65283 from liggitt/automated-cherry-pick-of-#65256-upstream-release-1.11
Automatic merge from submit-queue.

Automated cherry pick of #65256: bump(k8s.io/kube-openapi):

Fixes #65243

Cherry pick of #65256 on release-1.11.

#65256: bump(k8s.io/kube-openapi):

```release-note
fixed incorrect OpenAPI schema for CustomResourceDefinition objects
```

Kubernetes-commit: 5f5d6aa92b27bc300c631fd3fe26edc0f55fbb06
2018-06-21 07:31:03 +00:00
Jordan Liggitt
5c54f12e94 bump(k8s.io/kube-openapi): 91cfa479c814065e420cee7ed227db0f63a5854e
Kubernetes-commit: 7936a5bb822845c2a38d6f7da79bf3225e8faf1c
2018-06-19 23:23:00 -04:00
Kubernetes Publisher
11bffe824e Merge remote-tracking branch 'origin/master' into release-1.11
Kubernetes-commit: 61de6239b735f2d22a905247ca281bd6a4229989
2018-06-15 12:20:43 -04:00
Kubernetes Publisher
8560813064 Merge pull request #65034 from caesarxuchao/json-case-sensitive
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>.

Make kubernetes json serializer case sensitive

This PR imported the latest jsoniterator library so that case sensitivity during unmarhsaling is optional. The PR also set Kubernetes json serializer to be case sensitive.

Kubernetes json serializer had been case sensitive for 1.1-1.7 as we were using ugorji. This PR restores the behavior.

Fix #64612.

```release-notes
Kubernetes json deserializer is now case-sensitive as it was before 1.8.
If your config files contains fields with wrong case, the config files will be now invalid.
```

Kubernetes-commit: a2de1398f829ef38d645579160bdd6bfec8384d3
2018-06-15 19:30:00 +00:00
Kubernetes Publisher
2d1fce8ff8 Merge remote-tracking branch 'origin/master' into release-1.11
Kubernetes-commit: 465c3d5995501b90a608088e647e91f992896636
2018-06-14 15:30:10 +00:00
Andrew Lytvynov
ab6fed13f4 Re-use private key after failed CSR
If we create a new key on each CSR, if CSR fails the next attempt will
create a new one instead of reusing previous CSR.

If approver/signer don't handle CSRs as quickly as new nodes come up,
they can pile up and approver would keep handling old abandoned CSRs and
Nodes would keep timing out on startup.

Kubernetes-commit: 2c0f043957d25da162fe4e1026c50e2587529ff9
2018-06-13 11:27:25 -07:00
Kubernetes Publisher
cd89475a09 sync: update godeps 2018-06-11 19:28:49 +00:00
Chao Xu
0bb1a137a4 vendor the latest json-iterator
Kubernetes-commit: dd69be30a5f296102be6b9706e6ad0c5db8e2c0f
2018-06-10 16:48:43 -07:00
Kubernetes Publisher
94da772526 Merge remote-tracking branch 'origin/master' into release-1.11
Kubernetes-commit: d2d36588b7bf9819e7d6924d668ba217052e17cb
2018-06-08 15:32:04 +00:00
Jordan Liggitt
90da597c77 Revert "Auto-generated code for the Vertical Pod Autoscaler API."
This reverts commit da65f30e2aca4ca8177fcf27e95909e2883b6e20.

Kubernetes-commit: 846cbe4e6b63b198bd9926e59900f750168e6c69
2018-06-07 14:12:22 -04:00
Kubernetes Publisher
9aa389df39 Merge remote-tracking branch 'origin/master' into release-1.11
Kubernetes-commit: be2cfcf9e44b5162a294e977329d6c8194748c4e
2018-06-07 12:02:40 -04:00
Kubernetes Publisher
61801dc04d Merge pull request #63797 from kgrygiel/master
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>.

Add Vertical Pod Autoscaler to autoscaling/v2beta1

**What this PR does / why we need it**:
Adds Vertical Pod Autoscaler (https://github.com/kubernetes/community/blob/master/contributors/design-proposals/autoscaling/vertical-pod-autoscaler.md) to the autoscaling API (which currently has the Horizontal Pod Autoscaler).
This is needed for the Vertical Pod Autoscaler beta.

**Special notes for your reviewer**:

/cc @thockin @mwielgus @DirectXMan12

FYI. changes that add pkg/registry/autoscaling/verticalpodautoscaler/... will follow.

**Release note**:
```Add Vertical Pod Autoscaler to autoscaling/v2beta1.```

Kubernetes-commit: 63c90bb47ec99247cbf29542edfc443ffda7298b
2018-06-08 15:31:44 +00:00
Kubernetes Publisher
389936a9c8 Merge remote-tracking branch 'origin/master' into release-1.11. Deleting CHANGELOG-1.10.md
Kubernetes-commit: 96004088382e97c3fec454622b0304df344fb579
2018-06-06 12:58:08 -04:00
Kubernetes Publisher
75756cae80 Merge pull request #64719 from davidz627/feature/CSIv0.3
Automatic merge from submit-queue (batch tested with PRs 64276, 64094, 64719, 64766, 64750). 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>.

Upgrade container-storage-interface/spec dependency to v0.3.0

Also updated golang/protobuf to v1.1.0 to satisfy hard requirement of new CSI Spec version

/sig storage
/kind enhancement
/assign @saad-ali

```release-note
Updated Container Storage Interface specification version to v0.3.0
```

Kubernetes-commit: d12d8bd64bd25ce3a6bbda0dd43533cde359290b
2018-06-08 15:31:43 +00:00
Kubernetes Publisher
532187284b Merge remote-tracking branch 'origin/master' into release-1.11
Kubernetes-commit: f16c15909adccc7f8fb1423cbf4a7bd2274ff4f6
2018-06-05 13:24:34 -04:00
Kubernetes Publisher
4fcb07e80e Merge pull request #64482 from ericchiang/exec-plugin-beta
Automatic merge from submit-queue (batch tested with PRs 63453, 64592, 64482, 64618, 64661). 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: promote exec plugin support to beta

/sig auth
/kind feature

Adds a "v1beta1" API group for client authentication. Because of a lack of usage with the input parameters, these have been dropped for the beta. Would like to re-introduce them as users feel they require them.

updates https://github.com/kubernetes/kubernetes/issues/61796

```release-note
client-go: credential exec plugins have been promoted to beta
```

Kubernetes-commit: 819d51567f82c27ba3b7cde5b4cb3bb59c0550b6
2018-06-08 15:31:23 +00:00
Kubernetes Publisher
dc18462b71 Merge pull request #64596 from apelisse/openapi-some-cleanup
Automatic merge from submit-queue (batch tested with PRs 64613, 64596, 64573, 64154, 64639). 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>.

Openapi some cleanup

Clean-up some OpenAPI code, mostly test related (there are two implementations of "Fake").
This is going for master, but I'll probably also cherry-pick/create a similar PR for feature-serverside-apply branch since we'll need that to move some code around.

**What this PR does / why we need it**:

**Which issue(s) this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*:
Fixes #

**Special notes for your reviewer**:

**Release note**:

```release-note
NONE
```

Kubernetes-commit: c3bb41ad4b147f6159dd7542ffd2772d7042e2d8
2018-06-08 15:31:23 +00:00
Kubernetes Publisher
60d2f9ee1b Merge pull request #64408 from luxas/kubeadm_refactor_bt
Automatic merge from submit-queue (batch tested with PRs 64057, 63223, 64346, 64562, 64408). 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>.

kubeadm: Refactor the Bootstrap Tokens usage in the API types

**What this PR does / why we need it**:
This PR:
 - Moves some common, generic Bootstrap Token helpers and constants from `k8s.io/kubernetes/cmd/kubeadm/app/util/token` to `k8s.io/client-go/tools/bootstrap/token/`
 - Breaks out the top-level Bootstrap Token fields to a dedicated `BootstrapToken` struct with helper functions.
 - Instead of representing the Bootstrap Token as a plain `string`, there is now a wrapper struct `BootstrapTokenString` that can marshal/unmarshal correctly and supports validation on create, and splitting up the full token in the ID/Secret parts automatically.
 - Makes kubeadm support multiple Bootstrap Tokens automatically by supporting a slice of `BootstrapToken` in the `MasterConfiguration` API object
 - Consolidates the place for kubeadm to create token-related flags in an `options` package
 - Supports automatic conversion from the `v1alpha1` to `v1alpha2` API
 - Adds support to set token expiration directly instead of setting a TTL (Expiration and TTL are mutually exclusive)
 - Removes the old `TokenDiscovery` struct we're not using anymore inside of kubeadm

**Which issue(s) this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*:
Related to https://github.com/kubernetes/community/pull/2131

**Special notes for your reviewer**:
This is work in progress. Please only review the first two commits for now.
I will work on splitting up this PR in smaller chunks.
I will also write unit tests tomorrow.

**Release note**:

```release-note
[action required] kubeadm: The Token-related fields in the `MasterConfiguration` object have now been refactored. Instead of the top-level `.Token`, `.TokenTTL`, `.TokenUsages`, `.TokenGroups` fields, there is now a `BootstrapTokens` slice of `BootstrapToken` objects that support the same features under the `.Token`, `.TTL`, `.Usages`, `.Groups` fields.
```
@kubernetes/sig-cluster-lifecycle-pr-reviews @mattmoyer @liztio

Kubernetes-commit: c7b71ebca95d9afb5c4adbadf6cde09a0988d5a7
2018-06-08 15:31:03 +00:00
Kubernetes Publisher
37fcf22e5b Merge pull request #64346 from dims/deprecate-in-tree-keystone-plugin
Automatic merge from submit-queue (batch tested with PRs 64057, 63223, 64346, 64562, 64408). 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>.

Deprecate the in-tree keystone plugin

**What this PR does / why we need it**:

We now have the `client-keystone-auth` in cloud-provider-openstack
repository:
https://github.com/kubernetes/cloud-provider-openstack/blob/master/docs/using-client-keystone-auth.md

So let's drop the in-tree one, so we can remove it in 1.12

**Which issue(s) this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*:
Fixes #

**Special notes for your reviewer**:

**Release note**:

```release-note
in-tree support for openstack credentials is now deprecated. please use the "client-keystone-auth" from the cloud-provider-openstack repository. details on how to use this new capability is documented here - https://github.com/kubernetes/cloud-provider-openstack/blob/master/docs/using-client-keystone-auth.md
```

Kubernetes-commit: 10d0c5c19e8e0a0a8e3e4a1a9bfe6baf9cde1bc4
2018-06-08 15:31:02 +00:00
Kubernetes Publisher
a2802ecd41 Merge pull request #64262 from jessfraz/SECURITY_CONTACTS
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>.

add PST to main SECURITY_CONTACTS as formality

Add the Product Security Team as the security contacts for the main
repository and they can use the OWNERS files in each subsystem/dir to find
the correct owners.

cc @liggitt @cjcullen @tallclair @philips

```release-note
NONE
```

closes #64265

Signed-off-by: Jess Frazelle <acidburn@microsoft.com>

Kubernetes-commit: 5da925ad4fd070e687dc5255c177d5e7d542edd7
2018-06-08 15:31:01 +00:00
David Zhu
5e3044cdb8 staging godep update
Kubernetes-commit: cc3fb7e86112d9f436f2dce3a04fc729a2e13d15
2018-06-04 15:49:56 -07:00
Eric Chiang
15affbb73e client-go: make exec auth and auth provider mutually exclusive
Kubernetes-commit: d96fd39651a4182ceb016c879a17c6a237c87f53
2018-06-01 10:34:45 -07:00
Eric Chiang
a776f223c2 generated:
./hack/update-bazel.sh
	./hack/update-codegen.sh
	./hack/update-staging-godeps.sh

Kubernetes-commit: 206982723909944a2e68c3ffa9382f6b332e767a
2018-05-31 14:30:33 -07:00
Eric Chiang
8e3c4b8b5c client-go: promote exec plugin support to beta
Kubernetes-commit: 0a9164e73aedd898a535a64fcc992d3e50002d61
2018-05-31 14:28:27 -07:00
Eric Chiang
0243d85adf clientauthentication: add v1beta1 API version
Kubernetes-commit: 8952b8f7c99b75a9dc1aa47eb50770d218b2a8bf
2018-05-31 14:27:45 -07:00
Antoine Pelisse
e9e677202c Replace openapi Fake with kube-openapi version
There are two version of this fake class, let's just use that one
version.

Kubernetes-commit: 000510d9b73d5be870ebc763ea3606997107172c
2018-05-31 14:00:34 -07:00
Lucas Käldström
d0c8d510fb Move helper funcs and constants to the client-go Bootstrap Token package from kubeadm
Kubernetes-commit: 33f59e438e93b824492caff5d39fd143b43eac9a
2018-05-31 22:18:27 +03:00
kgrygiel
a6fa57c79c Auto-generated code for the Vertical Pod Autoscaler API.
Kubernetes-commit: da65f30e2aca4ca8177fcf27e95909e2883b6e20
2018-05-30 16:54:03 +02:00
Davanum Srinivas
f8adda79b7 Deprecate the in-tree keystone plugin
We now have the `client-keystone-auth` in cloud-provider-openstack
repository:
https://github.com/kubernetes/cloud-provider-openstack/blob/master/docs/using-client-keystone-auth.md

So let's drop the in-tree one, so we can remove it in 1.12

Kubernetes-commit: ffe817fcababca46d4989ff3982807468645d2ea
2018-05-25 15:55:49 -07:00
Jess Frazelle
c7ec09eb4f add PST to main SECURITY_CONTACTS as formality
Add the Product Security Team as the security contacts for the main
repository and they can use the OWNERS files in each subsystem/dir to find
the correct owners.

Signed-off-by: Jess Frazelle <acidburn@microsoft.com>

Kubernetes-commit: ac015892e4e2ab641a7761ab79f8cf986e1fa266
2018-05-24 09:33:43 -04:00
22 changed files with 1097 additions and 133 deletions

174
Godeps/Godeps.json generated
View File

@@ -68,23 +68,23 @@
},
{
"ImportPath": "github.com/golang/protobuf/proto",
"Rev": "1643683e1b54a9e88ad26d98f81400c8c9d9f4f9"
"Rev": "b4deda0973fb4c70b50d226b1af49f3da59f5265"
},
{
"ImportPath": "github.com/golang/protobuf/ptypes",
"Rev": "1643683e1b54a9e88ad26d98f81400c8c9d9f4f9"
"Rev": "b4deda0973fb4c70b50d226b1af49f3da59f5265"
},
{
"ImportPath": "github.com/golang/protobuf/ptypes/any",
"Rev": "1643683e1b54a9e88ad26d98f81400c8c9d9f4f9"
"Rev": "b4deda0973fb4c70b50d226b1af49f3da59f5265"
},
{
"ImportPath": "github.com/golang/protobuf/ptypes/duration",
"Rev": "1643683e1b54a9e88ad26d98f81400c8c9d9f4f9"
"Rev": "b4deda0973fb4c70b50d226b1af49f3da59f5265"
},
{
"ImportPath": "github.com/golang/protobuf/ptypes/timestamp",
"Rev": "1643683e1b54a9e88ad26d98f81400c8c9d9f4f9"
"Rev": "b4deda0973fb4c70b50d226b1af49f3da59f5265"
},
{
"ImportPath": "github.com/google/btree",
@@ -156,7 +156,7 @@
},
{
"ImportPath": "github.com/json-iterator/go",
"Rev": "2ddf6d758266fcb080a4f9e054b9f292c85e6798"
"Rev": "f2b4162afba35581b6d4a50d3b8f34e33c144682"
},
{
"ImportPath": "github.com/modern-go/concurrent",
@@ -268,327 +268,327 @@
},
{
"ImportPath": "k8s.io/api/admissionregistration/v1alpha1",
"Rev": "c71adde6150917c4e19dfef555f427d5e085f05d"
"Rev": "4e7be11eab3ffcfc1876898b8272df53785a9504"
},
{
"ImportPath": "k8s.io/api/admissionregistration/v1beta1",
"Rev": "c71adde6150917c4e19dfef555f427d5e085f05d"
"Rev": "4e7be11eab3ffcfc1876898b8272df53785a9504"
},
{
"ImportPath": "k8s.io/api/apps/v1",
"Rev": "c71adde6150917c4e19dfef555f427d5e085f05d"
"Rev": "4e7be11eab3ffcfc1876898b8272df53785a9504"
},
{
"ImportPath": "k8s.io/api/apps/v1beta1",
"Rev": "c71adde6150917c4e19dfef555f427d5e085f05d"
"Rev": "4e7be11eab3ffcfc1876898b8272df53785a9504"
},
{
"ImportPath": "k8s.io/api/apps/v1beta2",
"Rev": "c71adde6150917c4e19dfef555f427d5e085f05d"
"Rev": "4e7be11eab3ffcfc1876898b8272df53785a9504"
},
{
"ImportPath": "k8s.io/api/authentication/v1",
"Rev": "c71adde6150917c4e19dfef555f427d5e085f05d"
"Rev": "4e7be11eab3ffcfc1876898b8272df53785a9504"
},
{
"ImportPath": "k8s.io/api/authentication/v1beta1",
"Rev": "c71adde6150917c4e19dfef555f427d5e085f05d"
"Rev": "4e7be11eab3ffcfc1876898b8272df53785a9504"
},
{
"ImportPath": "k8s.io/api/authorization/v1",
"Rev": "c71adde6150917c4e19dfef555f427d5e085f05d"
"Rev": "4e7be11eab3ffcfc1876898b8272df53785a9504"
},
{
"ImportPath": "k8s.io/api/authorization/v1beta1",
"Rev": "c71adde6150917c4e19dfef555f427d5e085f05d"
"Rev": "4e7be11eab3ffcfc1876898b8272df53785a9504"
},
{
"ImportPath": "k8s.io/api/autoscaling/v1",
"Rev": "c71adde6150917c4e19dfef555f427d5e085f05d"
"Rev": "4e7be11eab3ffcfc1876898b8272df53785a9504"
},
{
"ImportPath": "k8s.io/api/autoscaling/v2beta1",
"Rev": "c71adde6150917c4e19dfef555f427d5e085f05d"
"Rev": "4e7be11eab3ffcfc1876898b8272df53785a9504"
},
{
"ImportPath": "k8s.io/api/batch/v1",
"Rev": "c71adde6150917c4e19dfef555f427d5e085f05d"
"Rev": "4e7be11eab3ffcfc1876898b8272df53785a9504"
},
{
"ImportPath": "k8s.io/api/batch/v1beta1",
"Rev": "c71adde6150917c4e19dfef555f427d5e085f05d"
"Rev": "4e7be11eab3ffcfc1876898b8272df53785a9504"
},
{
"ImportPath": "k8s.io/api/batch/v2alpha1",
"Rev": "c71adde6150917c4e19dfef555f427d5e085f05d"
"Rev": "4e7be11eab3ffcfc1876898b8272df53785a9504"
},
{
"ImportPath": "k8s.io/api/certificates/v1beta1",
"Rev": "c71adde6150917c4e19dfef555f427d5e085f05d"
"Rev": "4e7be11eab3ffcfc1876898b8272df53785a9504"
},
{
"ImportPath": "k8s.io/api/core/v1",
"Rev": "c71adde6150917c4e19dfef555f427d5e085f05d"
"Rev": "4e7be11eab3ffcfc1876898b8272df53785a9504"
},
{
"ImportPath": "k8s.io/api/events/v1beta1",
"Rev": "c71adde6150917c4e19dfef555f427d5e085f05d"
"Rev": "4e7be11eab3ffcfc1876898b8272df53785a9504"
},
{
"ImportPath": "k8s.io/api/extensions/v1beta1",
"Rev": "c71adde6150917c4e19dfef555f427d5e085f05d"
"Rev": "4e7be11eab3ffcfc1876898b8272df53785a9504"
},
{
"ImportPath": "k8s.io/api/imagepolicy/v1alpha1",
"Rev": "c71adde6150917c4e19dfef555f427d5e085f05d"
"Rev": "4e7be11eab3ffcfc1876898b8272df53785a9504"
},
{
"ImportPath": "k8s.io/api/networking/v1",
"Rev": "c71adde6150917c4e19dfef555f427d5e085f05d"
"Rev": "4e7be11eab3ffcfc1876898b8272df53785a9504"
},
{
"ImportPath": "k8s.io/api/policy/v1beta1",
"Rev": "c71adde6150917c4e19dfef555f427d5e085f05d"
"Rev": "4e7be11eab3ffcfc1876898b8272df53785a9504"
},
{
"ImportPath": "k8s.io/api/rbac/v1",
"Rev": "c71adde6150917c4e19dfef555f427d5e085f05d"
"Rev": "4e7be11eab3ffcfc1876898b8272df53785a9504"
},
{
"ImportPath": "k8s.io/api/rbac/v1alpha1",
"Rev": "c71adde6150917c4e19dfef555f427d5e085f05d"
"Rev": "4e7be11eab3ffcfc1876898b8272df53785a9504"
},
{
"ImportPath": "k8s.io/api/rbac/v1beta1",
"Rev": "c71adde6150917c4e19dfef555f427d5e085f05d"
"Rev": "4e7be11eab3ffcfc1876898b8272df53785a9504"
},
{
"ImportPath": "k8s.io/api/scheduling/v1alpha1",
"Rev": "c71adde6150917c4e19dfef555f427d5e085f05d"
"Rev": "4e7be11eab3ffcfc1876898b8272df53785a9504"
},
{
"ImportPath": "k8s.io/api/scheduling/v1beta1",
"Rev": "c71adde6150917c4e19dfef555f427d5e085f05d"
"Rev": "4e7be11eab3ffcfc1876898b8272df53785a9504"
},
{
"ImportPath": "k8s.io/api/settings/v1alpha1",
"Rev": "c71adde6150917c4e19dfef555f427d5e085f05d"
"Rev": "4e7be11eab3ffcfc1876898b8272df53785a9504"
},
{
"ImportPath": "k8s.io/api/storage/v1",
"Rev": "c71adde6150917c4e19dfef555f427d5e085f05d"
"Rev": "4e7be11eab3ffcfc1876898b8272df53785a9504"
},
{
"ImportPath": "k8s.io/api/storage/v1alpha1",
"Rev": "c71adde6150917c4e19dfef555f427d5e085f05d"
"Rev": "4e7be11eab3ffcfc1876898b8272df53785a9504"
},
{
"ImportPath": "k8s.io/api/storage/v1beta1",
"Rev": "c71adde6150917c4e19dfef555f427d5e085f05d"
"Rev": "4e7be11eab3ffcfc1876898b8272df53785a9504"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/api/equality",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/api/errors",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/api/meta",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/api/resource",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/api/testing",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/api/testing/fuzzer",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/api/testing/roundtrip",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/fuzzer",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/internalversion",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1beta1",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/conversion",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/conversion/queryparams",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/fields",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/labels",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/runtime",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/runtime/schema",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/json",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/protobuf",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/recognizer",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/streaming",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/versioning",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/selection",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/types",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/cache",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/clock",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/diff",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/errors",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/framer",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/httpstream",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/httpstream/spdy",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/intstr",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/json",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/mergepatch",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/net",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/remotecommand",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/runtime",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/sets",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/strategicpatch",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/validation",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/validation/field",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/wait",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/yaml",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/version",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/watch",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/json",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/netutil",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/reflect",
"Rev": "40bc35ef007c446a3ed3d1a2d51ed2d9f30f55f4"
"Rev": "def12e63c512da17043b4f0293f52d1006603d9f"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/util/proto",
"Rev": "86e28c192d2743f0232b9bc5f0a531568ef9f2a5"
"Rev": "91cfa479c814065e420cee7ed227db0f63a5854e"
}
]
}

17
SECURITY_CONTACTS Normal file
View File

@@ -0,0 +1,17 @@
# Defined below are the security contacts for this repo.
#
# They are the contact point for the Product Security Team to reach out
# to for triaging and handling of incoming issues.
#
# The below names agree to abide by the
# [Embargo Policy](https://github.com/kubernetes/sig-release/blob/master/security-release-process-documentation/security-release-process.md#embargo-policy)
# and will be removed and replaced if they violate that agreement.
#
# DO NOT REPORT SECURITY VULNERABILITIES DIRECTLY TO THESE NAMES, FOLLOW THE
# INSTRUCTIONS AT https://kubernetes.io/security/
cjcullen
jessfraz
liggitt
philips
tallclair

View File

@@ -0,0 +1,26 @@
/*
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 v1beta1
import (
conversion "k8s.io/apimachinery/pkg/conversion"
clientauthentication "k8s.io/client-go/pkg/apis/clientauthentication"
)
func Convert_clientauthentication_ExecCredentialSpec_To_v1beta1_ExecCredentialSpec(in *clientauthentication.ExecCredentialSpec, out *ExecCredentialSpec, s conversion.Scope) error {
return nil
}

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 v1beta1 // import "k8s.io/client-go/pkg/apis/clientauthentication/v1beta1"

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 v1beta1
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: "v1beta1"}
// 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,59 @@
/*
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 v1beta1
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{}
// ExecCredentialStatus holds credentials for the transport to use.
//
// Token and ClientKeyData are sensitive fields. This data should only be
// transmitted in-memory between client and exec plugin process. Exec plugin
// itself should at least be protected via file permissions.
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"`
// PEM-encoded client TLS certificates (including intermediates, if any).
ClientCertificateData string `json:"clientCertificateData,omitempty"`
// PEM-encoded private key for the above certificate.
ClientKeyData string `json:"clientKeyData,omitempty"`
}

View File

@@ -0,0 +1,114 @@
// +build !ignore_autogenerated
/*
Copyright 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 v1beta1
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_v1beta1_ExecCredential_To_clientauthentication_ExecCredential,
Convert_clientauthentication_ExecCredential_To_v1beta1_ExecCredential,
Convert_v1beta1_ExecCredentialSpec_To_clientauthentication_ExecCredentialSpec,
Convert_clientauthentication_ExecCredentialSpec_To_v1beta1_ExecCredentialSpec,
Convert_v1beta1_ExecCredentialStatus_To_clientauthentication_ExecCredentialStatus,
Convert_clientauthentication_ExecCredentialStatus_To_v1beta1_ExecCredentialStatus,
)
}
func autoConvert_v1beta1_ExecCredential_To_clientauthentication_ExecCredential(in *ExecCredential, out *clientauthentication.ExecCredential, s conversion.Scope) error {
if err := Convert_v1beta1_ExecCredentialSpec_To_clientauthentication_ExecCredentialSpec(&in.Spec, &out.Spec, s); err != nil {
return err
}
out.Status = (*clientauthentication.ExecCredentialStatus)(unsafe.Pointer(in.Status))
return nil
}
// Convert_v1beta1_ExecCredential_To_clientauthentication_ExecCredential is an autogenerated conversion function.
func Convert_v1beta1_ExecCredential_To_clientauthentication_ExecCredential(in *ExecCredential, out *clientauthentication.ExecCredential, s conversion.Scope) error {
return autoConvert_v1beta1_ExecCredential_To_clientauthentication_ExecCredential(in, out, s)
}
func autoConvert_clientauthentication_ExecCredential_To_v1beta1_ExecCredential(in *clientauthentication.ExecCredential, out *ExecCredential, s conversion.Scope) error {
if err := Convert_clientauthentication_ExecCredentialSpec_To_v1beta1_ExecCredentialSpec(&in.Spec, &out.Spec, s); err != nil {
return err
}
out.Status = (*ExecCredentialStatus)(unsafe.Pointer(in.Status))
return nil
}
// Convert_clientauthentication_ExecCredential_To_v1beta1_ExecCredential is an autogenerated conversion function.
func Convert_clientauthentication_ExecCredential_To_v1beta1_ExecCredential(in *clientauthentication.ExecCredential, out *ExecCredential, s conversion.Scope) error {
return autoConvert_clientauthentication_ExecCredential_To_v1beta1_ExecCredential(in, out, s)
}
func autoConvert_v1beta1_ExecCredentialSpec_To_clientauthentication_ExecCredentialSpec(in *ExecCredentialSpec, out *clientauthentication.ExecCredentialSpec, s conversion.Scope) error {
return nil
}
// Convert_v1beta1_ExecCredentialSpec_To_clientauthentication_ExecCredentialSpec is an autogenerated conversion function.
func Convert_v1beta1_ExecCredentialSpec_To_clientauthentication_ExecCredentialSpec(in *ExecCredentialSpec, out *clientauthentication.ExecCredentialSpec, s conversion.Scope) error {
return autoConvert_v1beta1_ExecCredentialSpec_To_clientauthentication_ExecCredentialSpec(in, out, s)
}
func autoConvert_clientauthentication_ExecCredentialSpec_To_v1beta1_ExecCredentialSpec(in *clientauthentication.ExecCredentialSpec, out *ExecCredentialSpec, s conversion.Scope) error {
// WARNING: in.Response requires manual conversion: does not exist in peer-type
// WARNING: in.Interactive requires manual conversion: does not exist in peer-type
return nil
}
func autoConvert_v1beta1_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
out.ClientCertificateData = in.ClientCertificateData
out.ClientKeyData = in.ClientKeyData
return nil
}
// Convert_v1beta1_ExecCredentialStatus_To_clientauthentication_ExecCredentialStatus is an autogenerated conversion function.
func Convert_v1beta1_ExecCredentialStatus_To_clientauthentication_ExecCredentialStatus(in *ExecCredentialStatus, out *clientauthentication.ExecCredentialStatus, s conversion.Scope) error {
return autoConvert_v1beta1_ExecCredentialStatus_To_clientauthentication_ExecCredentialStatus(in, out, s)
}
func autoConvert_clientauthentication_ExecCredentialStatus_To_v1beta1_ExecCredentialStatus(in *clientauthentication.ExecCredentialStatus, out *ExecCredentialStatus, s conversion.Scope) error {
out.ExpirationTimestamp = (*v1.Time)(unsafe.Pointer(in.ExpirationTimestamp))
out.Token = in.Token
out.ClientCertificateData = in.ClientCertificateData
out.ClientKeyData = in.ClientKeyData
return nil
}
// Convert_clientauthentication_ExecCredentialStatus_To_v1beta1_ExecCredentialStatus is an autogenerated conversion function.
func Convert_clientauthentication_ExecCredentialStatus_To_v1beta1_ExecCredentialStatus(in *clientauthentication.ExecCredentialStatus, out *ExecCredentialStatus, s conversion.Scope) error {
return autoConvert_clientauthentication_ExecCredentialStatus_To_v1beta1_ExecCredentialStatus(in, out, s)
}

View File

@@ -0,0 +1,100 @@
// +build !ignore_autogenerated
/*
Copyright 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 v1beta1
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
out.Spec = in.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
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
}

View File

@@ -0,0 +1,32 @@
// +build !ignore_autogenerated
/*
Copyright 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 v1beta1
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

@@ -20,6 +20,7 @@ import (
"bytes"
"context"
"crypto/tls"
"errors"
"fmt"
"io"
"net"
@@ -38,6 +39,7 @@ import (
"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/pkg/apis/clientauthentication/v1beta1"
"k8s.io/client-go/tools/clientcmd/api"
"k8s.io/client-go/transport"
"k8s.io/client-go/util/connrotation"
@@ -51,6 +53,7 @@ var codecs = serializer.NewCodecFactory(scheme)
func init() {
v1.AddToGroupVersion(scheme, schema.GroupVersion{Version: "v1"})
v1alpha1.AddToScheme(scheme)
v1beta1.AddToScheme(scheme)
clientauthentication.AddToScheme(scheme)
}
@@ -61,6 +64,7 @@ var (
// The list of API versions we accept.
apiVersions = map[string]schema.GroupVersion{
v1alpha1.SchemeGroupVersion.String(): v1alpha1.SchemeGroupVersion,
v1beta1.SchemeGroupVersion.String(): v1beta1.SchemeGroupVersion,
}
)
@@ -175,21 +179,10 @@ func (a *Authenticator) UpdateTransportConfig(c *transport.Config) error {
return &roundTripper{a, rt}
}
getCert := c.TLS.GetCert
c.TLS.GetCert = func() (*tls.Certificate, error) {
// If previous GetCert is present and returns a valid non-nil
// certificate, use that. Otherwise use cert from exec plugin.
if getCert != nil {
cert, err := getCert()
if err != nil {
return nil, err
}
if cert != nil {
return cert, nil
}
}
return a.cert()
if c.TLS.GetCert != nil {
return errors.New("can't add TLS certificate callback: transport.Config.TLS.GetCert already set")
}
c.TLS.GetCert = a.cert
var dial func(ctx context.Context, network, addr string) (net.Conn, error)
if c.Dial != nil {
@@ -294,13 +287,18 @@ func (a *Authenticator) refreshCredsLocked(r *clientauthentication.Response) err
},
}
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))
if a.group == v1alpha1.SchemeGroupVersion {
// Input spec disabled for beta due to lack of use. Possibly re-enable this later if
// someone wants it back.
//
// See: https://github.com/kubernetes/kubernetes/issues/61796
data, err := runtime.Encode(codecs.LegacyCodec(a.group), cred)
if err != nil {
return fmt.Errorf("encode ExecCredentials: %v", err)
}
env = append(env, fmt.Sprintf("%s=%s", execInfoEnv, data))
}
stdout := &bytes.Buffer{}
cmd := exec.Command(a.cmd, a.args...)

View File

@@ -380,6 +380,72 @@ func TestRefreshCreds(t *testing.T) {
}`, certData),
wantErr: true,
},
{
name: "beta-basic-request",
config: api.ExecConfig{
APIVersion: "client.authentication.k8s.io/v1beta1",
},
output: `{
"kind": "ExecCredential",
"apiVersion": "client.authentication.k8s.io/v1beta1",
"status": {
"token": "foo-bar"
}
}`,
wantCreds: credentials{token: "foo-bar"},
},
{
name: "beta-expiry",
config: api.ExecConfig{
APIVersion: "client.authentication.k8s.io/v1beta1",
},
output: `{
"kind": "ExecCredential",
"apiVersion": "client.authentication.k8s.io/v1beta1",
"status": {
"token": "foo-bar",
"expirationTimestamp": "2006-01-02T15:04:05Z"
}
}`,
wantExpiry: time.Date(2006, 01, 02, 15, 04, 05, 0, time.UTC),
wantCreds: credentials{token: "foo-bar"},
},
{
name: "beta-no-group-version",
config: api.ExecConfig{
APIVersion: "client.authentication.k8s.io/v1beta1",
},
output: `{
"kind": "ExecCredential",
"status": {
"token": "foo-bar"
}
}`,
wantErr: true,
},
{
name: "beta-no-status",
config: api.ExecConfig{
APIVersion: "client.authentication.k8s.io/v1beta1",
},
output: `{
"kind": "ExecCredential",
"apiVersion":"client.authentication.k8s.io/v1beta1"
}`,
wantErr: true,
},
{
name: "beta-no-token",
config: api.ExecConfig{
APIVersion: "client.authentication.k8s.io/v1beta1",
},
output: `{
"kind": "ExecCredential",
"apiVersion":"client.authentication.k8s.io/v1beta1",
"status": {}
}`,
wantErr: true,
},
}
for _, test := range tests {
@@ -420,6 +486,13 @@ func TestRefreshCreds(t *testing.T) {
t.Errorf("expected expiry %v got %v", test.wantExpiry, a.exp)
}
if test.wantInput == "" {
if got := strings.TrimSpace(stderr.String()); got != "" {
t.Errorf("expected no input parameters, got %q", got)
}
return
}
compJSON(t, stderr.Bytes(), []byte(test.wantInput))
})
}

View File

@@ -140,6 +140,7 @@ func newOpenstackAuthProvider(_ string, config map[string]string, persister rest
var ttlDuration time.Duration
var err error
glog.Warningf("WARNING: in-tree openstack auth plugin is now deprecated. please use the \"client-keystone-auth\" kubectl/client-go credential plugin instead")
ttl, found := config["ttl"]
if !found {
ttlDuration = DefaultTTLDuration

View File

@@ -18,6 +18,7 @@ package rest
import (
"crypto/tls"
"errors"
"net/http"
"k8s.io/client-go/plugin/pkg/client/auth/exec"
@@ -83,6 +84,11 @@ func (c *Config) TransportConfig() (*transport.Config, error) {
},
Dial: c.Dial,
}
if c.ExecProvider != nil && c.AuthProvider != nil {
return nil, errors.New("execProvider and authProvider cannot be used in combination")
}
if c.ExecProvider != nil {
provider, err := exec.GetAuthenticator(c.ExecProvider)
if err != nil {

View File

@@ -99,18 +99,20 @@ func NewDiscoveryRESTMapper(groupResources []*APIGroupResources) meta.RESTMapper
scope = meta.RESTScopeRoot
}
// this is for legacy resources and servers which don't list singular forms. For those we must still guess.
if len(resource.SingularName) == 0 {
versionMapper.Add(gv.WithKind(resource.Kind), scope)
// TODO this is producing unsafe guesses that don't actually work, but it matches previous behavior
versionMapper.Add(gv.WithKind(resource.Kind+"List"), scope)
// if we have a slash, then this is a subresource and we shouldn't create mappings for those.
if strings.Contains(resource.Name, "/") {
continue
}
plural := gv.WithResource(resource.Name)
singular := gv.WithResource(resource.SingularName)
versionMapper.AddSpecific(gv.WithKind(resource.Kind), plural, singular, scope)
// this is for legacy resources and servers which don't list singular forms. For those we must still guess.
if len(resource.SingularName) == 0 {
_, singular = meta.UnsafeGuessKindToResource(gv.WithKind(resource.Kind))
}
versionMapper.AddSpecific(gv.WithKind(strings.ToLower(resource.Kind)), plural, singular, scope)
versionMapper.AddSpecific(gv.WithKind(resource.Kind), plural, singular, scope)
// TODO this is producing unsafe guesses that don't actually work, but it matches previous behavior
versionMapper.Add(gv.WithKind(resource.Kind+"List"), scope)
}

View File

@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
// Package api (pkg/bootstrap/token/api) contains constants and types needed for
// Package api (k8s.io/client-go/tools/bootstrap/token/api) contains constants and types needed for
// bootstrap tokens as maintained by the BootstrapSigner and TokenCleaner
// controllers (in pkg/controller/bootstrap)
// controllers (in k8s.io/kubernetes/pkg/controller/bootstrap)
package api // import "k8s.io/client-go/tools/bootstrap/token/api"

View File

@@ -86,14 +86,26 @@ const (
// authenticate as. The full username given is "system:bootstrap:<token-id>".
BootstrapUserPrefix = "system:bootstrap:"
// BootstrapGroupPattern is the valid regex pattern that all groups
// assigned to a bootstrap token by BootstrapTokenExtraGroupsKey must match.
// See also ValidateBootstrapGroupName().
BootstrapGroupPattern = "system:bootstrappers:[a-z0-9:-]{0,255}[a-z0-9]"
// BootstrapDefaultGroup is the default group for bootstrapping bearer
// tokens (in addition to any groups from BootstrapTokenExtraGroupsKey).
BootstrapDefaultGroup = "system:bootstrappers"
// BootstrapGroupPattern is the valid regex pattern that all groups
// assigned to a bootstrap token by BootstrapTokenExtraGroupsKey must match.
// See also util.ValidateBootstrapGroupName()
BootstrapGroupPattern = `\Asystem:bootstrappers:[a-z0-9:-]{0,255}[a-z0-9]\z`
// BootstrapTokenPattern defines the {id}.{secret} regular expression pattern
BootstrapTokenPattern = `\A([a-z0-9]{6})\.([a-z0-9]{16})\z`
// BootstrapTokenIDPattern defines token's id regular expression pattern
BootstrapTokenIDPattern = `\A([a-z0-9]{6})\z`
// BootstrapTokenIDBytes defines the number of bytes used for the Bootstrap Token's ID field
BootstrapTokenIDBytes = 6
// BootstrapTokenSecretBytes defines the number of bytes used the Bootstrap Token's Secret field
BootstrapTokenSecretBytes = 16
)
// KnownTokenUsages specifies the known functions a token will get.

View File

@@ -17,20 +17,101 @@ limitations under the License.
package util
import (
"bufio"
"crypto/rand"
"fmt"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/client-go/tools/bootstrap/token/api"
"regexp"
"strings"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/client-go/tools/bootstrap/token/api"
)
var bootstrapGroupRegexp = regexp.MustCompile(`\A` + api.BootstrapGroupPattern + `\z`)
// validBootstrapTokenChars defines the characters a bootstrap token can consist of
const validBootstrapTokenChars = "0123456789abcdefghijklmnopqrstuvwxyz"
var (
// BootstrapTokenRegexp is a compiled regular expression of TokenRegexpString
BootstrapTokenRegexp = regexp.MustCompile(api.BootstrapTokenPattern)
// BootstrapTokenIDRegexp is a compiled regular expression of TokenIDRegexpString
BootstrapTokenIDRegexp = regexp.MustCompile(api.BootstrapTokenIDPattern)
// BootstrapGroupRegexp is a compiled regular expression of BootstrapGroupPattern
BootstrapGroupRegexp = regexp.MustCompile(api.BootstrapGroupPattern)
)
// GenerateBootstrapToken generates a new, random Bootstrap Token.
func GenerateBootstrapToken() (string, error) {
tokenID, err := randBytes(api.BootstrapTokenIDBytes)
if err != nil {
return "", err
}
tokenSecret, err := randBytes(api.BootstrapTokenSecretBytes)
if err != nil {
return "", err
}
return TokenFromIDAndSecret(tokenID, tokenSecret), nil
}
// randBytes returns a random string consisting of the characters in
// validBootstrapTokenChars, with the length customized by the parameter
func randBytes(length int) (string, error) {
// len("0123456789abcdefghijklmnopqrstuvwxyz") = 36 which doesn't evenly divide
// the possible values of a byte: 256 mod 36 = 4. Discard any random bytes we
// read that are >= 252 so the bytes we evenly divide the character set.
const maxByteValue = 252
var (
b byte
err error
token = make([]byte, length)
)
reader := bufio.NewReaderSize(rand.Reader, length*2)
for i := range token {
for {
if b, err = reader.ReadByte(); err != nil {
return "", err
}
if b < maxByteValue {
break
}
}
token[i] = validBootstrapTokenChars[int(b)%len(validBootstrapTokenChars)]
}
return string(token), nil
}
// TokenFromIDAndSecret returns the full token which is of the form "{id}.{secret}"
func TokenFromIDAndSecret(id, secret string) string {
return fmt.Sprintf("%s.%s", id, secret)
}
// IsValidBootstrapToken returns whether the given string is valid as a Bootstrap Token and
// in other words satisfies the BootstrapTokenRegexp
func IsValidBootstrapToken(token string) bool {
return BootstrapTokenRegexp.MatchString(token)
}
// IsValidBootstrapTokenID returns whether the given string is valid as a Bootstrap Token ID and
// in other words satisfies the BootstrapTokenIDRegexp
func IsValidBootstrapTokenID(tokenID string) bool {
return BootstrapTokenIDRegexp.MatchString(tokenID)
}
// BootstrapTokenSecretName returns the expected name for the Secret storing the
// Bootstrap Token in the Kubernetes API.
func BootstrapTokenSecretName(tokenID string) string {
return fmt.Sprintf("%s%s", api.BootstrapTokenSecretPrefix, tokenID)
}
// ValidateBootstrapGroupName checks if the provided group name is a valid
// bootstrap group name. Returns nil if valid or a validation error if invalid.
// TODO(mattmoyer): this validation should migrate out to client-go (see https://github.com/kubernetes/client-go/issues/114)
func ValidateBootstrapGroupName(name string) error {
if bootstrapGroupRegexp.Match([]byte(name)) {
if BootstrapGroupRegexp.Match([]byte(name)) {
return nil
}
return fmt.Errorf("bootstrap group %q is invalid (must match %s)", name, api.BootstrapGroupPattern)
@@ -46,7 +127,7 @@ func ValidateUsages(usages []string) error {
}
}
if len(invalidUsages) > 0 {
return fmt.Errorf("invalide bootstrap token usage string: %s, valid usage options: %s", strings.Join(invalidUsages.List(), ","), strings.Join(api.KnownTokenUsages, ","))
return fmt.Errorf("invalid bootstrap token usage string: %s, valid usage options: %s", strings.Join(invalidUsages.List(), ","), strings.Join(api.KnownTokenUsages, ","))
}
return nil
}

View File

@@ -21,6 +21,143 @@ import (
"testing"
)
func TestGenerateBootstrapToken(t *testing.T) {
token, err := GenerateBootstrapToken()
if err != nil {
t.Fatalf("GenerateBootstrapToken returned an unexpected error: %+v", err)
}
if !IsValidBootstrapToken(token) {
t.Errorf("GenerateBootstrapToken didn't generate a valid token: %q", token)
}
}
func TestRandBytes(t *testing.T) {
var randTest = []int{
0,
1,
2,
3,
100,
}
for _, rt := range randTest {
actual, err := randBytes(rt)
if err != nil {
t.Errorf("failed randBytes: %v", err)
}
if len(actual) != rt {
t.Errorf("failed randBytes:\n\texpected: %d\n\t actual: %d\n", rt, len(actual))
}
}
}
func TestTokenFromIDAndSecret(t *testing.T) {
var tests = []struct {
id string
secret string
expected string
}{
{"foo", "bar", "foo.bar"}, // should use default
{"abcdef", "abcdef0123456789", "abcdef.abcdef0123456789"},
{"h", "b", "h.b"},
}
for _, rt := range tests {
actual := TokenFromIDAndSecret(rt.id, rt.secret)
if actual != rt.expected {
t.Errorf(
"failed TokenFromIDAndSecret:\n\texpected: %s\n\t actual: %s",
rt.expected,
actual,
)
}
}
}
func TestIsValidBootstrapToken(t *testing.T) {
var tests = []struct {
token string
expected bool
}{
{token: "", expected: false},
{token: ".", expected: false},
{token: "1234567890123456789012", expected: false}, // invalid parcel size
{token: "12345.1234567890123456", expected: false}, // invalid parcel size
{token: ".1234567890123456", expected: false}, // invalid parcel size
{token: "123456.", expected: false}, // invalid parcel size
{token: "123456:1234567890.123456", expected: false}, // invalid separation
{token: "abcdef:1234567890123456", expected: false}, // invalid separation
{token: "Abcdef.1234567890123456", expected: false}, // invalid token id
{token: "123456.AABBCCDDEEFFGGHH", expected: false}, // invalid token secret
{token: "123456.AABBCCD-EEFFGGHH", expected: false}, // invalid character
{token: "abc*ef.1234567890123456", expected: false}, // invalid character
{token: "abcdef.1234567890123456", expected: true},
{token: "123456.aabbccddeeffgghh", expected: true},
{token: "ABCDEF.abcdef0123456789", expected: false},
{token: "abcdef.abcdef0123456789", expected: true},
{token: "123456.1234560123456789", expected: true},
}
for _, rt := range tests {
actual := IsValidBootstrapToken(rt.token)
if actual != rt.expected {
t.Errorf(
"failed IsValidBootstrapToken for the token %q\n\texpected: %t\n\t actual: %t",
rt.token,
rt.expected,
actual,
)
}
}
}
func TestIsValidBootstrapTokenID(t *testing.T) {
var tests = []struct {
tokenID string
expected bool
}{
{tokenID: "", expected: false},
{tokenID: "1234567890123456789012", expected: false},
{tokenID: "12345", expected: false},
{tokenID: "Abcdef", expected: false},
{tokenID: "ABCDEF", expected: false},
{tokenID: "abcdef.", expected: false},
{tokenID: "abcdef", expected: true},
{tokenID: "123456", expected: true},
}
for _, rt := range tests {
actual := IsValidBootstrapTokenID(rt.tokenID)
if actual != rt.expected {
t.Errorf(
"failed IsValidBootstrapTokenID for the token %q\n\texpected: %t\n\t actual: %t",
rt.tokenID,
rt.expected,
actual,
)
}
}
}
func TestBootstrapTokenSecretName(t *testing.T) {
var tests = []struct {
tokenID string
expected string
}{
{"foo", "bootstrap-token-foo"},
{"bar", "bootstrap-token-bar"},
{"", "bootstrap-token-"},
{"abcdef", "bootstrap-token-abcdef"},
}
for _, rt := range tests {
actual := BootstrapTokenSecretName(rt.tokenID)
if actual != rt.expected {
t.Errorf(
"failed BootstrapTokenSecretName:\n\texpected: %s\n\t actual: %s",
rt.expected,
actual,
)
}
}
}
func TestValidateBootstrapGroupName(t *testing.T) {
tests := []struct {
name string

View File

@@ -129,7 +129,7 @@ func SetAuthProxyHeaders(req *http.Request, username string, groups []string, ex
}
for key, values := range extra {
for _, value := range values {
req.Header.Add("X-Remote-Extra-"+key, value)
req.Header.Add("X-Remote-Extra-"+headerKeyEscape(key), value)
}
}
}
@@ -246,7 +246,7 @@ func (rt *impersonatingRoundTripper) RoundTrip(req *http.Request) (*http.Respons
}
for k, vv := range rt.impersonate.Extra {
for _, v := range vv {
req.Header.Add(ImpersonateUserExtraHeaderPrefix+k, v)
req.Header.Add(ImpersonateUserExtraHeaderPrefix+headerKeyEscape(k), v)
}
}
@@ -422,3 +422,110 @@ func (rt *debuggingRoundTripper) RoundTrip(req *http.Request) (*http.Response, e
func (rt *debuggingRoundTripper) WrappedRoundTripper() http.RoundTripper {
return rt.delegatedRoundTripper
}
func legalHeaderByte(b byte) bool {
return int(b) < len(legalHeaderKeyBytes) && legalHeaderKeyBytes[b]
}
func shouldEscape(b byte) bool {
// url.PathUnescape() returns an error if any '%' is not followed by two
// hexadecimal digits, so we'll intentionally encode it.
return !legalHeaderByte(b) || b == '%'
}
func headerKeyEscape(key string) string {
buf := strings.Builder{}
for i := 0; i < len(key); i++ {
b := key[i]
if shouldEscape(b) {
// %-encode bytes that should be escaped:
// https://tools.ietf.org/html/rfc3986#section-2.1
fmt.Fprintf(&buf, "%%%02X", b)
continue
}
buf.WriteByte(b)
}
return buf.String()
}
// legalHeaderKeyBytes was copied from net/http/lex.go's isTokenTable.
// See https://httpwg.github.io/specs/rfc7230.html#rule.token.separators
var legalHeaderKeyBytes = [127]bool{
'%': true,
'!': true,
'#': true,
'$': true,
'&': true,
'\'': true,
'*': true,
'+': true,
'-': true,
'.': true,
'0': true,
'1': true,
'2': true,
'3': true,
'4': true,
'5': true,
'6': true,
'7': true,
'8': true,
'9': true,
'A': true,
'B': true,
'C': true,
'D': true,
'E': true,
'F': true,
'G': true,
'H': true,
'I': true,
'J': true,
'K': true,
'L': true,
'M': true,
'N': true,
'O': true,
'P': true,
'Q': true,
'R': true,
'S': true,
'T': true,
'U': true,
'W': true,
'V': true,
'X': true,
'Y': true,
'Z': true,
'^': true,
'_': true,
'`': true,
'a': true,
'b': true,
'c': true,
'd': true,
'e': true,
'f': true,
'g': true,
'h': true,
'i': true,
'j': true,
'k': true,
'l': true,
'm': true,
'n': true,
'o': true,
'p': true,
'q': true,
'r': true,
's': true,
't': true,
'u': true,
'v': true,
'w': true,
'x': true,
'y': true,
'z': true,
'|': true,
'~': true,
}

View File

@@ -18,6 +18,7 @@ package transport
import (
"net/http"
"net/url"
"reflect"
"strings"
"testing"
@@ -125,6 +126,32 @@ func TestImpersonationRoundTripper(t *testing.T) {
ImpersonateUserExtraHeaderPrefix + "Second": {"B", "b"},
},
},
{
name: "escape handling",
impersonationConfig: ImpersonationConfig{
UserName: "user",
Extra: map[string][]string{
"test.example.com/thing.thing": {"A", "a"},
},
},
expected: map[string][]string{
ImpersonateUserHeader: {"user"},
ImpersonateUserExtraHeaderPrefix + `Test.example.com%2fthing.thing`: {"A", "a"},
},
},
{
name: "double escape handling",
impersonationConfig: ImpersonationConfig{
UserName: "user",
Extra: map[string][]string{
"test.example.com/thing.thing%20another.thing": {"A", "a"},
},
},
expected: map[string][]string{
ImpersonateUserHeader: {"user"},
ImpersonateUserExtraHeaderPrefix + `Test.example.com%2fthing.thing%2520another.thing`: {"A", "a"},
},
},
}
for _, tc := range tcs {
@@ -159,9 +186,10 @@ func TestImpersonationRoundTripper(t *testing.T) {
func TestAuthProxyRoundTripper(t *testing.T) {
for n, tc := range map[string]struct {
username string
groups []string
extra map[string][]string
username string
groups []string
extra map[string][]string
expectedExtra map[string][]string
}{
"allfields": {
username: "user",
@@ -170,6 +198,34 @@ func TestAuthProxyRoundTripper(t *testing.T) {
"one": {"alpha", "bravo"},
"two": {"charlie", "delta"},
},
expectedExtra: map[string][]string{
"one": {"alpha", "bravo"},
"two": {"charlie", "delta"},
},
},
"escaped extra": {
username: "user",
groups: []string{"groupA", "groupB"},
extra: map[string][]string{
"one": {"alpha", "bravo"},
"example.com/two": {"charlie", "delta"},
},
expectedExtra: map[string][]string{
"one": {"alpha", "bravo"},
"example.com%2ftwo": {"charlie", "delta"},
},
},
"double escaped extra": {
username: "user",
groups: []string{"groupA", "groupB"},
extra: map[string][]string{
"one": {"alpha", "bravo"},
"example.com/two%20three": {"charlie", "delta"},
},
expectedExtra: map[string][]string{
"one": {"alpha", "bravo"},
"example.com%2ftwo%2520three": {"charlie", "delta"},
},
},
} {
rt := &testRoundTripper{}
@@ -210,9 +266,64 @@ func TestAuthProxyRoundTripper(t *testing.T) {
actualExtra[extraKey] = append(actualExtra[key], values...)
}
}
if e, a := tc.extra, actualExtra; !reflect.DeepEqual(e, a) {
if e, a := tc.expectedExtra, actualExtra; !reflect.DeepEqual(e, a) {
t.Errorf("%s expected %v, got %v", n, e, a)
continue
}
}
}
// TestHeaderEscapeRoundTrip tests to see if foo == url.PathUnescape(headerEscape(foo))
// This behavior is important for client -> API server transmission of extra values.
func TestHeaderEscapeRoundTrip(t *testing.T) {
t.Parallel()
testCases := []struct {
name string
key string
}{
{
name: "alpha",
key: "alphabetical",
},
{
name: "alphanumeric",
key: "alph4num3r1c",
},
{
name: "percent encoded",
key: "percent%20encoded",
},
{
name: "almost percent encoded",
key: "almost%zzpercent%xxencoded",
},
{
name: "illegal char & percent encoding",
key: "example.com/percent%20encoded",
},
{
name: "weird unicode stuff",
key: "example.com/ᛒᚥᛏᛖᚥᚢとロビン",
},
{
name: "header legal chars",
key: "abc123!#$+.-_*\\^`~|'",
},
{
name: "legal path, illegal header",
key: "@=:",
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
escaped := headerKeyEscape(tc.key)
unescaped, err := url.PathUnescape(escaped)
if err != nil {
t.Fatalf("url.PathUnescape(%q) returned error: %v", escaped, err)
}
if tc.key != unescaped {
t.Errorf("url.PathUnescape(headerKeyEscape(%q)) returned %q, wanted %q", tc.key, unescaped, tc.key)
}
})
}
}

View File

@@ -88,7 +88,8 @@ func WriteKey(keyPath string, data []byte) error {
// can't find one, it will generate a new key and store it there.
func LoadOrGenerateKeyFile(keyPath string) (data []byte, wasGenerated bool, err error) {
loadedData, err := ioutil.ReadFile(keyPath)
if err == nil {
// Call verifyKeyData to ensure the file wasn't empty/corrupt.
if err == nil && verifyKeyData(loadedData) {
return loadedData, false, err
}
if !os.IsNotExist(err) {
@@ -181,3 +182,12 @@ func PublicKeysFromFile(file string) ([]interface{}, error) {
}
return keys, nil
}
// verifyKeyData returns true if the provided data appears to be a valid private key.
func verifyKeyData(data []byte) bool {
if len(data) == 0 {
return false
}
_, err := ParsePrivateKeyPEM(data)
return err == nil
}