Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
0727219c
Commit
0727219c
authored
Nov 11, 2014
by
Eric Tune
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
New package defines .kubernetes_auth format.
Refactored common code to that package. Subsequent PRs will load and emit these files.
parent
91d7a19f
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
228 additions
and
63 deletions
+228
-63
e2e.go
cmd/e2e/e2e.go
+5
-10
kubecfg.go
cmd/kubecfg/kubecfg.go
+2
-1
clientauth.go
pkg/clientauth/clientauth.go
+119
-0
clientauth_test.go
pkg/clientauth/clientauth_test.go
+69
-0
kubecfg.go
pkg/kubecfg/kubecfg.go
+8
-19
kubecfg_test.go
pkg/kubecfg/kubecfg_test.go
+7
-6
cmd.go
pkg/kubectl/cmd/cmd.go
+3
-1
kubectl.go
pkg/kubectl/kubectl.go
+7
-19
kubectl_test.go
pkg/kubectl/kubectl_test.go
+8
-7
No files found.
cmd/e2e/e2e.go
View file @
0727219c
...
...
@@ -27,7 +27,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/
kubecfg
"
"github.com/GoogleCloudPlatform/kubernetes/pkg/
clientauth
"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/golang/glog"
...
...
@@ -78,18 +78,13 @@ func loadClientOrDie() *client.Client {
config
:=
client
.
Config
{
Host
:
*
host
,
}
auth
,
err
:=
kubecfg
.
LoadAuthInfo
(
*
authConfig
,
os
.
Stdin
)
auth
,
err
:=
clientauth
.
LoadFromFile
(
*
authConfig
)
if
err
!=
nil
{
glog
.
Fatalf
(
"Error loading auth: %v"
,
err
)
}
config
.
Username
=
auth
.
User
config
.
Password
=
auth
.
Password
config
.
CAFile
=
auth
.
CAFile
config
.
CertFile
=
auth
.
CertFile
config
.
KeyFile
=
auth
.
KeyFile
config
.
BearerToken
=
auth
.
BearerToken
if
auth
.
Insecure
!=
nil
{
config
.
Insecure
=
*
auth
.
Insecure
config
,
err
=
auth
.
MergeWithConfig
(
config
)
if
err
!=
nil
{
glog
.
Fatalf
(
"Error creating client"
)
}
c
,
err
:=
client
.
New
(
&
config
)
if
err
!=
nil
{
...
...
cmd/kubecfg/kubecfg.go
View file @
0727219c
...
...
@@ -199,10 +199,11 @@ func main() {
if
clientConfig
.
Host
==
""
{
// TODO: eventually apiserver should start on 443 and be secure by default
// TODO: don't specify http or https in Host, and infer that from auth options.
clientConfig
.
Host
=
"http://localhost:8080"
}
if
client
.
IsConfigTransportTLS
(
clientConfig
)
{
auth
,
err
:=
kubecfg
.
Load
AuthInfo
(
*
authConfig
,
os
.
Stdin
)
auth
,
err
:=
kubecfg
.
Load
ClientAuthInfoOrPrompt
(
*
authConfig
,
os
.
Stdin
)
if
err
!=
nil
{
glog
.
Fatalf
(
"Error loading auth: %v"
,
err
)
}
...
...
pkg/clientauth/clientauth.go
0 → 100644
View file @
0727219c
/*
Copyright 2014 Google Inc. All rights reserved.
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 authcfg defines a file format for holding authentication
information needed by clients of Kubernetes. Typically,
a Kubernetes cluster will put auth info for the admin in a known
location when it is created, and will (soon) put it in a known
location within a Container's file tree for Containers that
need access to the Kubernetes API.
Having a defined format allows:
- clients to be implmented in multiple languages
- applications which link clients to be portable across
clusters with different authentication styles (e.g.
some may use SSL Client certs, others may not, etc)
- when the format changes, applications only
need to update this code.
The file format is json, marshalled from a struct authcfg.Info.
Clinet libraries in other languages should use the same format.
It is not intended to store general preferences, such as default
namespace, output options, etc. CLIs (such as kubectl) and UIs should
develop their own format and may wish to inline the authcfg.Info type.
The authcfg.Info is just a file format. It is distinct from
client.Config which holds options for creating a client.Client.
Helper functions are provided in this package to fill in a
client.Client from an authcfg.Info.
Example:
import (
"pkg/client"
"pkg/clientauth"
)
info, err := clientauth.LoadFromFile(filename)
if err != nil {
// handle error
}
clientConfig = client.Config{}
clientConfig.Host = "example.com:4901"
clientConfig = info.MergeWithConfig()
client := client.New(clientConfig)
client.ListPods()
*/
package
clientauth
// TODO: need a way to rotate Tokens. Therefore, need a way for client object to be reset when the authcfg is updated.
import
(
"encoding/json"
"io/ioutil"
"os"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
)
// Info holds Kubernetes API authorization config. It is intended
// to be read/written from a file as a JSON object.
type
Info
struct
{
User
string
Password
string
CAFile
string
CertFile
string
KeyFile
string
BearerToken
string
Insecure
*
bool
}
// LoadFromFile parses an Info object from a file path.
// If the file does not exist, then os.IsNotExist(err) == true
func
LoadFromFile
(
path
string
)
(
*
Info
,
error
)
{
var
info
Info
if
_
,
err
:=
os
.
Stat
(
path
);
os
.
IsNotExist
(
err
)
{
return
nil
,
err
}
data
,
err
:=
ioutil
.
ReadFile
(
path
)
if
err
!=
nil
{
return
nil
,
err
}
err
=
json
.
Unmarshal
(
data
,
&
info
)
if
err
!=
nil
{
return
nil
,
err
}
return
&
info
,
err
}
// MergeWithConfig returns a copy of a client.Config with values from the Info.
// The fields of client.Config with a corresponding field in the Info are set
// with the value from the Info.
func
(
info
Info
)
MergeWithConfig
(
c
client
.
Config
)
(
client
.
Config
,
error
)
{
var
config
client
.
Config
=
c
config
.
Username
=
info
.
User
config
.
Password
=
info
.
Password
config
.
CAFile
=
info
.
CAFile
config
.
CertFile
=
info
.
CertFile
config
.
KeyFile
=
info
.
KeyFile
config
.
BearerToken
=
info
.
BearerToken
if
info
.
Insecure
!=
nil
{
config
.
Insecure
=
*
info
.
Insecure
}
return
config
,
nil
}
pkg/clientauth/clientauth_test.go
0 → 100644
View file @
0727219c
/*
Copyright 2014 Google Inc. All rights reserved.
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
clientauth_test
import
(
"io/ioutil"
"os"
"reflect"
"testing"
"github.com/GoogleCloudPlatform/kubernetes/pkg/clientauth"
)
func
TestLoadFromFile
(
t
*
testing
.
T
)
{
loadAuthInfoTests
:=
[]
struct
{
authData
string
authInfo
*
clientauth
.
Info
expectErr
bool
}{
{
`{"user": "user", "password": "pass"}`
,
&
clientauth
.
Info
{
User
:
"user"
,
Password
:
"pass"
},
false
,
},
{
""
,
nil
,
true
,
},
}
for
_
,
loadAuthInfoTest
:=
range
loadAuthInfoTests
{
tt
:=
loadAuthInfoTest
aifile
,
err
:=
ioutil
.
TempFile
(
""
,
"testAuthInfo"
)
if
err
!=
nil
{
t
.
Errorf
(
"Unexpected error: %v"
,
err
)
}
if
tt
.
authData
!=
"missing"
{
defer
os
.
Remove
(
aifile
.
Name
())
defer
aifile
.
Close
()
_
,
err
=
aifile
.
WriteString
(
tt
.
authData
)
if
err
!=
nil
{
t
.
Errorf
(
"Unexpected error: %v"
,
err
)
}
}
else
{
aifile
.
Close
()
os
.
Remove
(
aifile
.
Name
())
}
authInfo
,
err
:=
clientauth
.
LoadFromFile
(
aifile
.
Name
())
gotErr
:=
err
!=
nil
if
gotErr
!=
tt
.
expectErr
{
t
.
Errorf
(
"expected errorness: %v, actual errorness: %v"
,
tt
.
expectErr
,
gotErr
)
}
if
!
reflect
.
DeepEqual
(
authInfo
,
tt
.
authInfo
)
{
t
.
Errorf
(
"Expected %v, got %v"
,
tt
.
authInfo
,
authInfo
)
}
}
}
pkg/kubecfg/kubecfg.go
View file @
0727219c
...
...
@@ -28,6 +28,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/clientauth"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util/wait"
...
...
@@ -51,23 +52,15 @@ func promptForString(field string, r io.Reader) string {
return
result
}
type
AuthInfo
struct
{
User
string
Password
string
CAFile
string
CertFile
string
KeyFile
string
BearerToken
string
Insecure
*
bool
}
type
NamespaceInfo
struct
{
Namespace
string
}
// LoadAuthInfo parses an AuthInfo object from a file path. It prompts user and creates file if it doesn't exist.
func
LoadAuthInfo
(
path
string
,
r
io
.
Reader
)
(
*
AuthInfo
,
error
)
{
var
auth
AuthInfo
// LoadClientAuthInfoOrPrompt parses a clientauth.Info object from a file path. It prompts user and creates file if it doesn't exist.
// Oddly, it returns a clientauth.Info even if there is an error.
func
LoadClientAuthInfoOrPrompt
(
path
string
,
r
io
.
Reader
)
(
*
clientauth
.
Info
,
error
)
{
var
auth
clientauth
.
Info
// Prompt for user/pass and write a file if none exists.
if
_
,
err
:=
os
.
Stat
(
path
);
os
.
IsNotExist
(
err
)
{
auth
.
User
=
promptForString
(
"Username"
,
r
)
auth
.
Password
=
promptForString
(
"Password"
,
r
)
...
...
@@ -78,15 +71,11 @@ func LoadAuthInfo(path string, r io.Reader) (*AuthInfo, error) {
err
=
ioutil
.
WriteFile
(
path
,
data
,
0600
)
return
&
auth
,
err
}
data
,
err
:=
ioutil
.
ReadFile
(
path
)
if
err
!=
nil
{
return
nil
,
err
}
err
=
json
.
Unmarshal
(
data
,
&
auth
)
authPtr
,
err
:=
clientauth
.
LoadFromFile
(
path
)
if
err
!=
nil
{
return
nil
,
err
}
return
&
auth
,
err
return
authPtr
,
nil
}
// LoadNamespaceInfo parses a NamespaceInfo object from a file path. It creates a file at the specified path if it doesn't exist with the default namespace.
...
...
pkg/kubecfg/kubecfg_test.go
View file @
0727219c
...
...
@@ -26,6 +26,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/clientauth"
)
func
validateAction
(
expectedAction
,
actualAction
client
.
FakeAction
,
t
*
testing
.
T
)
{
...
...
@@ -290,15 +291,15 @@ func TestLoadNamespaceInfo(t *testing.T) {
}
}
func
TestLoad
AuthInfo
(
t
*
testing
.
T
)
{
func
TestLoad
ClientAuthInfoOrPrompt
(
t
*
testing
.
T
)
{
loadAuthInfoTests
:=
[]
struct
{
authData
string
authInfo
*
Auth
Info
authInfo
*
clientauth
.
Info
r
io
.
Reader
}{
{
`{"user": "user", "password": "pass"}`
,
&
Auth
Info
{
User
:
"user"
,
Password
:
"pass"
},
&
clientauth
.
Info
{
User
:
"user"
,
Password
:
"pass"
},
nil
,
},
{
...
...
@@ -306,7 +307,7 @@ func TestLoadAuthInfo(t *testing.T) {
},
{
"missing"
,
&
Auth
Info
{
User
:
"user"
,
Password
:
"pass"
},
&
clientauth
.
Info
{
User
:
"user"
,
Password
:
"pass"
},
bytes
.
NewBufferString
(
"user
\n
pass"
),
},
}
...
...
@@ -327,10 +328,10 @@ func TestLoadAuthInfo(t *testing.T) {
aifile
.
Close
()
os
.
Remove
(
aifile
.
Name
())
}
authInfo
,
err
:=
Load
AuthInfo
(
aifile
.
Name
(),
tt
.
r
)
authInfo
,
err
:=
Load
ClientAuthInfoOrPrompt
(
aifile
.
Name
(),
tt
.
r
)
if
len
(
tt
.
authData
)
==
0
&&
tt
.
authData
!=
"missing"
{
if
err
==
nil
{
t
.
Error
(
"Load
AuthInfo
didn't fail on empty file"
)
t
.
Error
(
"Load
ClientAuthInfoOrPrompt
didn't fail on empty file"
)
}
continue
}
...
...
pkg/kubectl/cmd/cmd.go
View file @
0727219c
...
...
@@ -175,7 +175,9 @@ func GetKubeConfig(cmd *cobra.Command) *client.Config {
// command line). Override them with the command line parameters, if
// provided.
authPath
:=
GetFlagString
(
cmd
,
"auth-path"
)
authInfo
,
err
:=
kubectl
.
LoadAuthInfo
(
authPath
,
os
.
Stdin
)
authInfo
,
err
:=
kubectl
.
LoadClientAuthInfoOrPrompt
(
authPath
,
os
.
Stdin
)
// TODO: handle the case where the file could not be written but
// we still got a user/pass from prompting.
if
err
!=
nil
{
glog
.
Fatalf
(
"Error loading auth: %v"
,
err
)
}
...
...
pkg/kubectl/kubectl.go
View file @
0727219c
...
...
@@ -28,6 +28,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/clientauth"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/version"
...
...
@@ -56,16 +57,6 @@ func GetKubeClient(config *client.Config, matchVersion bool) (*client.Client, er
return
c
,
nil
}
type
AuthInfo
struct
{
User
string
Password
string
CAFile
string
CertFile
string
KeyFile
string
BearerToken
string
Insecure
*
bool
}
type
NamespaceInfo
struct
{
Namespace
string
}
...
...
@@ -99,9 +90,10 @@ func SaveNamespaceInfo(path string, ns *NamespaceInfo) error {
return
err
}
// LoadAuthInfo parses an AuthInfo object from a file path. It prompts user and creates file if it doesn't exist.
func
LoadAuthInfo
(
path
string
,
r
io
.
Reader
)
(
*
AuthInfo
,
error
)
{
var
auth
AuthInfo
// LoadClientAuthInfoOrPrompt parses an AuthInfo object from a file path. It prompts user and creates file if it doesn't exist.
func
LoadClientAuthInfoOrPrompt
(
path
string
,
r
io
.
Reader
)
(
*
clientauth
.
Info
,
error
)
{
var
auth
clientauth
.
Info
// Prompt for user/pass and write a file if none exists.
if
_
,
err
:=
os
.
Stat
(
path
);
os
.
IsNotExist
(
err
)
{
auth
.
User
=
promptForString
(
"Username"
,
r
)
auth
.
Password
=
promptForString
(
"Password"
,
r
)
...
...
@@ -112,15 +104,11 @@ func LoadAuthInfo(path string, r io.Reader) (*AuthInfo, error) {
err
=
ioutil
.
WriteFile
(
path
,
data
,
0600
)
return
&
auth
,
err
}
data
,
err
:=
ioutil
.
ReadFile
(
path
)
if
err
!=
nil
{
return
nil
,
err
}
err
=
json
.
Unmarshal
(
data
,
&
auth
)
authPtr
,
err
:=
clientauth
.
LoadFromFile
(
path
)
if
err
!=
nil
{
return
nil
,
err
}
return
&
auth
,
err
return
authPtr
,
nil
}
func
promptForString
(
field
string
,
r
io
.
Reader
)
string
{
...
...
pkg/kubectl/kubectl_test.go
View file @
0727219c
...
...
@@ -25,6 +25,7 @@ import (
"testing"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/clientauth"
)
func
validateAction
(
expectedAction
,
actualAction
client
.
FakeAction
,
t
*
testing
.
T
)
{
...
...
@@ -85,15 +86,15 @@ func TestLoadNamespaceInfo(t *testing.T) {
}
}
func
TestLoad
AuthInfo
(
t
*
testing
.
T
)
{
func
TestLoad
ClientAuthInfoOrPrompt
(
t
*
testing
.
T
)
{
loadAuthInfoTests
:=
[]
struct
{
authData
string
authInfo
*
Auth
Info
authInfo
*
clientauth
.
Info
r
io
.
Reader
}{
{
`{"user": "user", "password": "pass"}`
,
&
Auth
Info
{
User
:
"user"
,
Password
:
"pass"
},
&
clientauth
.
Info
{
User
:
"user"
,
Password
:
"pass"
},
nil
,
},
{
...
...
@@ -101,7 +102,7 @@ func TestLoadAuthInfo(t *testing.T) {
},
{
"missing"
,
&
Auth
Info
{
User
:
"user"
,
Password
:
"pass"
},
&
clientauth
.
Info
{
User
:
"user"
,
Password
:
"pass"
},
bytes
.
NewBufferString
(
"user
\n
pass"
),
},
}
...
...
@@ -122,10 +123,10 @@ func TestLoadAuthInfo(t *testing.T) {
aifile
.
Close
()
os
.
Remove
(
aifile
.
Name
())
}
authInfo
,
err
:=
Load
AuthInfo
(
aifile
.
Name
(),
tt
.
r
)
authInfo
,
err
:=
Load
ClientAuthInfoOrPrompt
(
aifile
.
Name
(),
tt
.
r
)
if
len
(
tt
.
authData
)
==
0
&&
tt
.
authData
!=
"missing"
{
if
err
==
nil
{
t
.
Error
(
"Load
AuthInfo
didn't fail on empty file"
)
t
.
Error
(
"Load
ClientAuthInfoOrPrompt
didn't fail on empty file"
)
}
continue
}
...
...
@@ -133,7 +134,7 @@ func TestLoadAuthInfo(t *testing.T) {
t
.
Errorf
(
"Unexpected error: %v"
,
err
)
}
if
!
reflect
.
DeepEqual
(
authInfo
,
tt
.
authInfo
)
{
t
.
Errorf
(
"Expected %
v, got %
v"
,
tt
.
authInfo
,
authInfo
)
t
.
Errorf
(
"Expected %
#v, got %#
v"
,
tt
.
authInfo
,
authInfo
)
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment