1
0
Fork 0

Vendor main dependencies.

This commit is contained in:
Timo Reimann 2017-02-07 22:33:23 +01:00
parent 49a09ab7dd
commit dd5e3fba01
2738 changed files with 1045689 additions and 0 deletions

View file

@ -0,0 +1,105 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package gcp
import (
"net/http"
"time"
"github.com/golang/glog"
"golang.org/x/net/context"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
"k8s.io/client-go/1.5/rest"
)
func init() {
if err := rest.RegisterAuthProviderPlugin("gcp", newGCPAuthProvider); err != nil {
glog.Fatalf("Failed to register gcp auth plugin: %v", err)
}
}
type gcpAuthProvider struct {
tokenSource oauth2.TokenSource
persister rest.AuthProviderConfigPersister
}
func newGCPAuthProvider(_ string, gcpConfig map[string]string, persister rest.AuthProviderConfigPersister) (rest.AuthProvider, error) {
ts, err := newCachedTokenSource(gcpConfig["access-token"], gcpConfig["expiry"], persister)
if err != nil {
return nil, err
}
return &gcpAuthProvider{ts, persister}, nil
}
func (g *gcpAuthProvider) WrapTransport(rt http.RoundTripper) http.RoundTripper {
return &oauth2.Transport{
Source: g.tokenSource,
Base: rt,
}
}
func (g *gcpAuthProvider) Login() error { return nil }
type cachedTokenSource struct {
source oauth2.TokenSource
accessToken string
expiry time.Time
persister rest.AuthProviderConfigPersister
}
func newCachedTokenSource(accessToken, expiry string, persister rest.AuthProviderConfigPersister) (*cachedTokenSource, error) {
var expiryTime time.Time
if parsedTime, err := time.Parse(time.RFC3339Nano, expiry); err == nil {
expiryTime = parsedTime
}
ts, err := google.DefaultTokenSource(context.Background(), "https://www.googleapis.com/auth/cloud-platform")
if err != nil {
return nil, err
}
return &cachedTokenSource{
source: ts,
accessToken: accessToken,
expiry: expiryTime,
persister: persister,
}, nil
}
func (t *cachedTokenSource) Token() (*oauth2.Token, error) {
tok := &oauth2.Token{
AccessToken: t.accessToken,
TokenType: "Bearer",
Expiry: t.expiry,
}
if tok.Valid() && !tok.Expiry.IsZero() {
return tok, nil
}
tok, err := t.source.Token()
if err != nil {
return nil, err
}
if t.persister != nil {
cached := map[string]string{
"access-token": tok.AccessToken,
"expiry": tok.Expiry.Format(time.RFC3339Nano),
}
if err := t.persister.Persist(cached); err != nil {
glog.V(4).Infof("Failed to persist token: %v", err)
}
}
return tok, nil
}

View file

@ -0,0 +1,270 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package oidc
import (
"encoding/base64"
"errors"
"fmt"
"net/http"
"strings"
"time"
"github.com/coreos/go-oidc/jose"
"github.com/coreos/go-oidc/oauth2"
"github.com/coreos/go-oidc/oidc"
"github.com/golang/glog"
"k8s.io/client-go/1.5/pkg/util/wait"
"k8s.io/client-go/1.5/rest"
)
const (
cfgIssuerUrl = "idp-issuer-url"
cfgClientID = "client-id"
cfgClientSecret = "client-secret"
cfgCertificateAuthority = "idp-certificate-authority"
cfgCertificateAuthorityData = "idp-certificate-authority-data"
cfgExtraScopes = "extra-scopes"
cfgIDToken = "id-token"
cfgRefreshToken = "refresh-token"
)
var (
backoff = wait.Backoff{
Duration: 1 * time.Second,
Factor: 2,
Jitter: .1,
Steps: 5,
}
)
func init() {
if err := rest.RegisterAuthProviderPlugin("oidc", newOIDCAuthProvider); err != nil {
glog.Fatalf("Failed to register oidc auth plugin: %v", err)
}
}
func newOIDCAuthProvider(_ string, cfg map[string]string, persister rest.AuthProviderConfigPersister) (rest.AuthProvider, error) {
issuer := cfg[cfgIssuerUrl]
if issuer == "" {
return nil, fmt.Errorf("Must provide %s", cfgIssuerUrl)
}
clientID := cfg[cfgClientID]
if clientID == "" {
return nil, fmt.Errorf("Must provide %s", cfgClientID)
}
clientSecret := cfg[cfgClientSecret]
if clientSecret == "" {
return nil, fmt.Errorf("Must provide %s", cfgClientSecret)
}
var certAuthData []byte
var err error
if cfg[cfgCertificateAuthorityData] != "" {
certAuthData, err = base64.StdEncoding.DecodeString(cfg[cfgCertificateAuthorityData])
if err != nil {
return nil, err
}
}
clientConfig := rest.Config{
TLSClientConfig: rest.TLSClientConfig{
CAFile: cfg[cfgCertificateAuthority],
CAData: certAuthData,
},
}
trans, err := rest.TransportFor(&clientConfig)
if err != nil {
return nil, err
}
hc := &http.Client{Transport: trans}
providerCfg, err := oidc.FetchProviderConfig(hc, issuer)
if err != nil {
return nil, fmt.Errorf("error fetching provider config: %v", err)
}
scopes := strings.Split(cfg[cfgExtraScopes], ",")
oidcCfg := oidc.ClientConfig{
HTTPClient: hc,
Credentials: oidc.ClientCredentials{
ID: clientID,
Secret: clientSecret,
},
ProviderConfig: providerCfg,
Scope: append(scopes, oidc.DefaultScope...),
}
client, err := oidc.NewClient(oidcCfg)
if err != nil {
return nil, fmt.Errorf("error creating OIDC Client: %v", err)
}
oClient := &oidcClient{client}
var initialIDToken jose.JWT
if cfg[cfgIDToken] != "" {
initialIDToken, err = jose.ParseJWT(cfg[cfgIDToken])
if err != nil {
return nil, err
}
}
return &oidcAuthProvider{
initialIDToken: initialIDToken,
refresher: &idTokenRefresher{
client: oClient,
cfg: cfg,
persister: persister,
},
}, nil
}
type oidcAuthProvider struct {
refresher *idTokenRefresher
initialIDToken jose.JWT
}
func (g *oidcAuthProvider) WrapTransport(rt http.RoundTripper) http.RoundTripper {
at := &oidc.AuthenticatedTransport{
TokenRefresher: g.refresher,
RoundTripper: rt,
}
at.SetJWT(g.initialIDToken)
return &roundTripper{
wrapped: at,
refresher: g.refresher,
}
}
func (g *oidcAuthProvider) Login() error {
return errors.New("not yet implemented")
}
type OIDCClient interface {
refreshToken(rt string) (oauth2.TokenResponse, error)
verifyJWT(jwt jose.JWT) error
}
type roundTripper struct {
refresher *idTokenRefresher
wrapped *oidc.AuthenticatedTransport
}
func (r *roundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
var res *http.Response
var err error
firstTime := true
wait.ExponentialBackoff(backoff, func() (bool, error) {
if !firstTime {
var jwt jose.JWT
jwt, err = r.refresher.Refresh()
if err != nil {
return true, nil
}
r.wrapped.SetJWT(jwt)
} else {
firstTime = false
}
res, err = r.wrapped.RoundTrip(req)
if err != nil {
return true, nil
}
if res.StatusCode == http.StatusUnauthorized {
return false, nil
}
return true, nil
})
return res, err
}
type idTokenRefresher struct {
cfg map[string]string
client OIDCClient
persister rest.AuthProviderConfigPersister
intialIDToken jose.JWT
}
func (r *idTokenRefresher) Verify(jwt jose.JWT) error {
claims, err := jwt.Claims()
if err != nil {
return err
}
now := time.Now()
exp, ok, err := claims.TimeClaim("exp")
switch {
case err != nil:
return fmt.Errorf("failed to parse 'exp' claim: %v", err)
case !ok:
return errors.New("missing required 'exp' claim")
case exp.Before(now):
return fmt.Errorf("token already expired at: %v", exp)
}
return nil
}
func (r *idTokenRefresher) Refresh() (jose.JWT, error) {
rt, ok := r.cfg[cfgRefreshToken]
if !ok {
return jose.JWT{}, errors.New("No valid id-token, and cannot refresh without refresh-token")
}
tokens, err := r.client.refreshToken(rt)
if err != nil {
return jose.JWT{}, fmt.Errorf("could not refresh token: %v", err)
}
jwt, err := jose.ParseJWT(tokens.IDToken)
if err != nil {
return jose.JWT{}, err
}
if tokens.RefreshToken != "" && tokens.RefreshToken != rt {
r.cfg[cfgRefreshToken] = tokens.RefreshToken
}
r.cfg[cfgIDToken] = jwt.Encode()
err = r.persister.Persist(r.cfg)
if err != nil {
return jose.JWT{}, fmt.Errorf("could not perist new tokens: %v", err)
}
return jwt, r.client.verifyJWT(jwt)
}
type oidcClient struct {
client *oidc.Client
}
func (o *oidcClient) refreshToken(rt string) (oauth2.TokenResponse, error) {
oac, err := o.client.OAuthClient()
if err != nil {
return oauth2.TokenResponse{}, err
}
return oac.RequestToken(oauth2.GrantTypeRefreshToken, rt)
}
func (o *oidcClient) verifyJWT(jwt jose.JWT) error {
return o.client.VerifyJWT(jwt)
}

View file

@ -0,0 +1,23 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package auth
import (
// Initialize all known client auth plugins.
_ "k8s.io/client-go/1.5/plugin/pkg/client/auth/gcp"
_ "k8s.io/client-go/1.5/plugin/pkg/client/auth/oidc"
)