github.com/enmand/kubernetes@v1.2.0-alpha.0/pkg/credentialprovider/gcp/jwt.go (about)

     1  /*
     2  Copyright 2014 The Kubernetes Authors All rights reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package gcp_credentials
    18  
    19  import (
    20  	"io/ioutil"
    21  	"time"
    22  
    23  	"github.com/golang/glog"
    24  	"golang.org/x/oauth2"
    25  	"golang.org/x/oauth2/google"
    26  	"golang.org/x/oauth2/jwt"
    27  	"k8s.io/kubernetes/pkg/credentialprovider"
    28  
    29  	"github.com/spf13/pflag"
    30  )
    31  
    32  const (
    33  	storageReadOnlyScope = "https://www.googleapis.com/auth/devstorage.read_only"
    34  )
    35  
    36  var (
    37  	flagJwtFile = pflag.String("google-json-key", "",
    38  		"The Google Cloud Platform Service Account JSON Key to use for authentication.")
    39  )
    40  
    41  // A DockerConfigProvider that reads its configuration from Google
    42  // Compute Engine metadata.
    43  type jwtProvider struct {
    44  	path     *string
    45  	config   *jwt.Config
    46  	tokenUrl string
    47  }
    48  
    49  // init registers the various means by which credentials may
    50  // be resolved on GCP.
    51  func init() {
    52  	credentialprovider.RegisterCredentialProvider("google-jwt-key",
    53  		&credentialprovider.CachingDockerConfigProvider{
    54  			Provider: &jwtProvider{
    55  				path: flagJwtFile,
    56  			},
    57  			Lifetime: 30 * time.Minute,
    58  		})
    59  }
    60  
    61  // Enabled implements DockerConfigProvider for the JSON Key based implementation.
    62  func (j *jwtProvider) Enabled() bool {
    63  	if *j.path == "" {
    64  		return false
    65  	}
    66  
    67  	data, err := ioutil.ReadFile(*j.path)
    68  	if err != nil {
    69  		glog.Errorf("while reading file %s got %v", *j.path, err)
    70  		return false
    71  	}
    72  	config, err := google.JWTConfigFromJSON(data, storageReadOnlyScope)
    73  	if err != nil {
    74  		glog.Errorf("while parsing %s data got %v", *j.path, err)
    75  		return false
    76  	}
    77  
    78  	j.config = config
    79  	if j.tokenUrl != "" {
    80  		j.config.TokenURL = j.tokenUrl
    81  	}
    82  	return true
    83  }
    84  
    85  // Provide implements DockerConfigProvider
    86  func (j *jwtProvider) Provide() credentialprovider.DockerConfig {
    87  	cfg := credentialprovider.DockerConfig{}
    88  
    89  	ts := j.config.TokenSource(oauth2.NoContext)
    90  	token, err := ts.Token()
    91  	if err != nil {
    92  		glog.Errorf("while exchanging json key %s for access token %v", *j.path, err)
    93  		return cfg
    94  	}
    95  	if !token.Valid() {
    96  		glog.Errorf("Got back invalid token: %v", token)
    97  		return cfg
    98  	}
    99  
   100  	entry := credentialprovider.DockerConfigEntry{
   101  		Username: "_token",
   102  		Password: token.AccessToken,
   103  		Email:    j.config.Email,
   104  	}
   105  
   106  	// Add our entry for each of the supported container registry URLs
   107  	for _, k := range containerRegistryUrls {
   108  		cfg[k] = entry
   109  	}
   110  	return cfg
   111  }