add kubectl config
This commit is contained in:
40
pkg/client/clientcmd/api/latest/latest.go
Normal file
40
pkg/client/clientcmd/api/latest/latest.go
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
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 latest
|
||||
|
||||
import (
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd/api/v1"
|
||||
)
|
||||
|
||||
// Version is the string that represents the current external default version.
|
||||
const Version = "v1"
|
||||
|
||||
// OldestVersion is the string that represents the oldest server version supported,
|
||||
// for client code that wants to hardcode the lowest common denominator.
|
||||
const OldestVersion = "v1"
|
||||
|
||||
// Versions is the list of versions that are recognized in code. The order provided
|
||||
// may be assumed to be least feature rich to most feature rich, and clients may
|
||||
// choose to prefer the latter items in the list over the former items when presented
|
||||
// with a set of versions to choose.
|
||||
var Versions = []string{"v1"}
|
||||
|
||||
// Codec is the default codec for serializing output that should use
|
||||
// the latest supported version. Use this Codec when writing to
|
||||
// disk, a data store that is not dynamically versioned, or in tests.
|
||||
// This codec can decode any object that Kubernetes is aware of.
|
||||
var Codec = v1.Codec
|
32
pkg/client/clientcmd/api/register.go
Normal file
32
pkg/client/clientcmd/api/register.go
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
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 api
|
||||
|
||||
import (
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
)
|
||||
|
||||
// Scheme is the default instance of runtime.Scheme to which types in the Kubernetes API are already registered.
|
||||
var Scheme = runtime.NewScheme()
|
||||
|
||||
func init() {
|
||||
Scheme.AddKnownTypes("",
|
||||
&Config{},
|
||||
)
|
||||
}
|
||||
|
||||
func (*Config) IsAnAPIObject() {}
|
119
pkg/client/clientcmd/api/types.go
Normal file
119
pkg/client/clientcmd/api/types.go
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
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 api
|
||||
|
||||
import (
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
)
|
||||
|
||||
// Where possible, json tags match the cli argument names.
|
||||
// Top level config objects and all values required for proper functioning are not "omitempty". Any truly optional piece of config is allowed to be omitted.
|
||||
|
||||
// Config holds the information needed to build connect to remote kubernetes clusters as a given user
|
||||
type Config struct {
|
||||
api.TypeMeta `json:",inline"`
|
||||
// Preferences holds general information to be use for cli interactions
|
||||
Preferences Preferences `json:"preferences"`
|
||||
// Clusters is a map of referencable names to cluster configs
|
||||
Clusters map[string]Cluster `json:"clusters"`
|
||||
// AuthInfos is a map of referencable names to user configs
|
||||
AuthInfos map[string]AuthInfo `json:"users"`
|
||||
// Contexts is a map of referencable names to context configs
|
||||
Contexts map[string]Context `json:"contexts"`
|
||||
// CurrentContext is the name of the context that you would like to use by default
|
||||
CurrentContext string `json:"current-context"`
|
||||
// Extensions holds additional information. This is useful for extenders so that reads and writes don't clobber unknown fields
|
||||
Extensions map[string]runtime.EmbeddedObject `json:"extensions,omitempty"`
|
||||
}
|
||||
|
||||
type Preferences struct {
|
||||
Colors bool `json:"colors,omitempty"`
|
||||
// Extensions holds additional information. This is useful for extenders so that reads and writes don't clobber unknown fields
|
||||
Extensions map[string]runtime.EmbeddedObject `json:"extensions,omitempty"`
|
||||
}
|
||||
|
||||
// Cluster contains information about how to communicate with a kubernetes cluster
|
||||
type Cluster struct {
|
||||
// Server is the address of the kubernetes cluster (https://hostname:port).
|
||||
Server string `json:"server"`
|
||||
// APIVersion is the preferred api version for communicating with the kubernetes cluster (v1beta1, v1beta2, v1beta3, etc).
|
||||
APIVersion string `json:"api-version,omitempty"`
|
||||
// InsecureSkipTLSVerify skips the validity check for the server's certificate. This will make your HTTPS connections insecure.
|
||||
InsecureSkipTLSVerify bool `json:"insecure-skip-tls-verify,omitempty"`
|
||||
// CertificateAuthority is the path to a cert file for the certificate authority.
|
||||
CertificateAuthority string `json:"certificate-authority,omitempty"`
|
||||
// Extensions holds additional information. This is useful for extenders so that reads and writes don't clobber unknown fields
|
||||
Extensions map[string]runtime.EmbeddedObject `json:"extensions,omitempty"`
|
||||
}
|
||||
|
||||
// AuthInfo contains information that describes identity information. This is use to tell the kubernetes cluster who you are.
|
||||
type AuthInfo struct {
|
||||
// AuthPath is the path to a kubernetes auth file (~/.kubernetes_auth). If you provide an AuthPath, the other options specified are ignored
|
||||
AuthPath string `json:"auth-path,omitempty"`
|
||||
// ClientCertificate is the path to a client cert file for TLS.
|
||||
ClientCertificate string `json:"client-certificate,omitempty"`
|
||||
// ClientKey is the path to a client key file for TLS.
|
||||
ClientKey string `json:"client-key,omitempty"`
|
||||
// Token is the bearer token for authentication to the kubernetes cluster.
|
||||
Token string `json:"token,omitempty"`
|
||||
// Extensions holds additional information. This is useful for extenders so that reads and writes don't clobber unknown fields
|
||||
Extensions map[string]runtime.EmbeddedObject `json:"extensions,omitempty"`
|
||||
}
|
||||
|
||||
// Context is a tuple of references to a cluster (how do I communicate with a kubernetes cluster), a user (how do I identify myself), and a namespace (what subset of resources do I want to work with)
|
||||
type Context struct {
|
||||
// Cluster is the name of the cluster for this context
|
||||
Cluster string `json:"cluster"`
|
||||
// AuthInfo is the name of the authInfo for this context
|
||||
AuthInfo string `json:"user"`
|
||||
// Namespace is the default namespace to use on unspecified requests
|
||||
Namespace string `json:"namespace,omitempty"`
|
||||
// Extensions holds additional information. This is useful for extenders so that reads and writes don't clobber unknown fields
|
||||
Extensions map[string]runtime.EmbeddedObject `json:"extensions,omitempty"`
|
||||
}
|
||||
|
||||
// NewConfig is a convenience function that returns a new Config object with non-nil maps
|
||||
func NewConfig() *Config {
|
||||
return &Config{
|
||||
Preferences: *NewPreferences(),
|
||||
Clusters: make(map[string]Cluster),
|
||||
AuthInfos: make(map[string]AuthInfo),
|
||||
Contexts: make(map[string]Context),
|
||||
Extensions: make(map[string]runtime.EmbeddedObject),
|
||||
}
|
||||
}
|
||||
|
||||
// NewConfig is a convenience function that returns a new Config object with non-nil maps
|
||||
func NewContext() *Context {
|
||||
return &Context{Extensions: make(map[string]runtime.EmbeddedObject)}
|
||||
}
|
||||
|
||||
// NewConfig is a convenience function that returns a new Config object with non-nil maps
|
||||
func NewCluster() *Cluster {
|
||||
return &Cluster{Extensions: make(map[string]runtime.EmbeddedObject)}
|
||||
}
|
||||
|
||||
// NewConfig is a convenience function that returns a new Config object with non-nil maps
|
||||
func NewAuthInfo() *AuthInfo {
|
||||
return &AuthInfo{Extensions: make(map[string]runtime.EmbeddedObject)}
|
||||
}
|
||||
|
||||
// NewConfig is a convenience function that returns a new Config object with non-nil maps
|
||||
func NewPreferences() *Preferences {
|
||||
return &Preferences{Extensions: make(map[string]runtime.EmbeddedObject)}
|
||||
}
|
@@ -14,12 +14,12 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package clientcmd
|
||||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"gopkg.in/v2/yaml"
|
||||
"github.com/ghodss/yaml"
|
||||
)
|
||||
|
||||
func ExampleEmptyConfig() {
|
||||
@@ -32,11 +32,11 @@ func ExampleEmptyConfig() {
|
||||
|
||||
fmt.Printf("%v", string(output))
|
||||
// Output:
|
||||
// preferences: {}
|
||||
// clusters: {}
|
||||
// users: {}
|
||||
// contexts: {}
|
||||
// current-context: ""
|
||||
// preferences: {}
|
||||
// users: {}
|
||||
}
|
||||
|
||||
func ExampleOfOptionsConfig() {
|
||||
@@ -86,17 +86,30 @@ func ExampleOfOptionsConfig() {
|
||||
|
||||
fmt.Printf("%v", string(output))
|
||||
// Output:
|
||||
// preferences:
|
||||
// colors: true
|
||||
// clusters:
|
||||
// alfa:
|
||||
// server: https://alfa.org:8080
|
||||
// api-version: v1beta2
|
||||
// insecure-skip-tls-verify: true
|
||||
// certificate-authority: path/to/my/cert-ca-filename
|
||||
// insecure-skip-tls-verify: true
|
||||
// server: https://alfa.org:8080
|
||||
// bravo:
|
||||
// server: https://bravo.org:8080
|
||||
// api-version: v1beta1
|
||||
// server: https://bravo.org:8080
|
||||
// contexts:
|
||||
// alfa-as-black-mage:
|
||||
// cluster: alfa
|
||||
// namespace: zulu
|
||||
// user: black-mage-via-file
|
||||
// alfa-as-white-mage:
|
||||
// cluster: alfa
|
||||
// user: white-mage-via-cert
|
||||
// bravo-as-black-mage:
|
||||
// cluster: bravo
|
||||
// namespace: yankee
|
||||
// user: black-mage-via-file
|
||||
// current-context: alfa-as-white-mage
|
||||
// preferences:
|
||||
// colors: true
|
||||
// users:
|
||||
// black-mage-via-file:
|
||||
// auth-path: path/to/my/.kubernetes_auth
|
||||
@@ -105,17 +118,4 @@ func ExampleOfOptionsConfig() {
|
||||
// white-mage-via-cert:
|
||||
// client-certificate: path/to/my/client-cert-filename
|
||||
// client-key: path/to/my/client-key-filename
|
||||
// contexts:
|
||||
// alfa-as-black-mage:
|
||||
// cluster: alfa
|
||||
// user: black-mage-via-file
|
||||
// namespace: zulu
|
||||
// alfa-as-white-mage:
|
||||
// cluster: alfa
|
||||
// user: white-mage-via-cert
|
||||
// bravo-as-black-mage:
|
||||
// cluster: bravo
|
||||
// user: black-mage-via-file
|
||||
// namespace: yankee
|
||||
// current-context: alfa-as-white-mage
|
||||
}
|
206
pkg/client/clientcmd/api/v1/conversion.go
Normal file
206
pkg/client/clientcmd/api/v1/conversion.go
Normal file
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
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 v1
|
||||
|
||||
import (
|
||||
"sort"
|
||||
|
||||
newer "github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/conversion"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
)
|
||||
|
||||
func init() {
|
||||
err := newer.Scheme.AddConversionFuncs(
|
||||
func(in *Config, out *newer.Config, s conversion.Scope) error {
|
||||
out.CurrentContext = in.CurrentContext
|
||||
if err := s.Convert(&in.Preferences, &out.Preferences, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
out.Clusters = make(map[string]newer.Cluster)
|
||||
if err := s.Convert(&in.Clusters, &out.Clusters, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
out.AuthInfos = make(map[string]newer.AuthInfo)
|
||||
if err := s.Convert(&in.AuthInfos, &out.AuthInfos, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
out.Contexts = make(map[string]newer.Context)
|
||||
if err := s.Convert(&in.Contexts, &out.Contexts, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
out.Extensions = make(map[string]runtime.EmbeddedObject)
|
||||
if err := s.Convert(&in.Extensions, &out.Extensions, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
},
|
||||
func(in *newer.Config, out *Config, s conversion.Scope) error {
|
||||
out.CurrentContext = in.CurrentContext
|
||||
if err := s.Convert(&in.Preferences, &out.Preferences, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
out.Clusters = make([]NamedCluster, 0, 0)
|
||||
if err := s.Convert(&in.Clusters, &out.Clusters, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
out.AuthInfos = make([]NamedAuthInfo, 0, 0)
|
||||
if err := s.Convert(&in.AuthInfos, &out.AuthInfos, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
out.Contexts = make([]NamedContext, 0, 0)
|
||||
if err := s.Convert(&in.Contexts, &out.Contexts, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
out.Extensions = make([]NamedExtension, 0, 0)
|
||||
if err := s.Convert(&in.Extensions, &out.Extensions, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
},
|
||||
func(in *[]NamedCluster, out *map[string]newer.Cluster, s conversion.Scope) error {
|
||||
for _, curr := range *in {
|
||||
newCluster := newer.NewCluster()
|
||||
if err := s.Convert(&curr.Cluster, newCluster, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
(*out)[curr.Name] = *newCluster
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
func(in *map[string]newer.Cluster, out *[]NamedCluster, s conversion.Scope) error {
|
||||
allKeys := make([]string, 0, len(*in))
|
||||
for key := range *in {
|
||||
allKeys = append(allKeys, key)
|
||||
}
|
||||
sort.Strings(allKeys)
|
||||
|
||||
for _, key := range allKeys {
|
||||
newCluster := (*in)[key]
|
||||
oldCluster := &Cluster{}
|
||||
if err := s.Convert(&newCluster, oldCluster, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
namedCluster := NamedCluster{key, *oldCluster}
|
||||
*out = append(*out, namedCluster)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
func(in *[]NamedAuthInfo, out *map[string]newer.AuthInfo, s conversion.Scope) error {
|
||||
for _, curr := range *in {
|
||||
newAuthInfo := newer.NewAuthInfo()
|
||||
if err := s.Convert(&curr.AuthInfo, newAuthInfo, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
(*out)[curr.Name] = *newAuthInfo
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
func(in *map[string]newer.AuthInfo, out *[]NamedAuthInfo, s conversion.Scope) error {
|
||||
allKeys := make([]string, 0, len(*in))
|
||||
for key := range *in {
|
||||
allKeys = append(allKeys, key)
|
||||
}
|
||||
sort.Strings(allKeys)
|
||||
|
||||
for _, key := range allKeys {
|
||||
newAuthInfo := (*in)[key]
|
||||
oldAuthInfo := &AuthInfo{}
|
||||
if err := s.Convert(&newAuthInfo, oldAuthInfo, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
namedAuthInfo := NamedAuthInfo{key, *oldAuthInfo}
|
||||
*out = append(*out, namedAuthInfo)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
func(in *[]NamedContext, out *map[string]newer.Context, s conversion.Scope) error {
|
||||
for _, curr := range *in {
|
||||
newContext := newer.NewContext()
|
||||
if err := s.Convert(&curr.Context, newContext, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
(*out)[curr.Name] = *newContext
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
func(in *map[string]newer.Context, out *[]NamedContext, s conversion.Scope) error {
|
||||
allKeys := make([]string, 0, len(*in))
|
||||
for key := range *in {
|
||||
allKeys = append(allKeys, key)
|
||||
}
|
||||
sort.Strings(allKeys)
|
||||
|
||||
for _, key := range allKeys {
|
||||
newContext := (*in)[key]
|
||||
oldContext := &Context{}
|
||||
if err := s.Convert(&newContext, oldContext, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
namedContext := NamedContext{key, *oldContext}
|
||||
*out = append(*out, namedContext)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
func(in *[]NamedExtension, out *map[string]runtime.EmbeddedObject, s conversion.Scope) error {
|
||||
for _, curr := range *in {
|
||||
newExtension := &runtime.EmbeddedObject{}
|
||||
if err := s.Convert(&curr.Extension, newExtension, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
(*out)[curr.Name] = *newExtension
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
func(in *map[string]runtime.EmbeddedObject, out *[]NamedExtension, s conversion.Scope) error {
|
||||
allKeys := make([]string, 0, len(*in))
|
||||
for key := range *in {
|
||||
allKeys = append(allKeys, key)
|
||||
}
|
||||
sort.Strings(allKeys)
|
||||
|
||||
for _, key := range allKeys {
|
||||
newExtension := (*in)[key]
|
||||
oldExtension := &runtime.RawExtension{}
|
||||
if err := s.Convert(&newExtension, oldExtension, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
namedExtension := NamedExtension{key, *oldExtension}
|
||||
*out = append(*out, namedExtension)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
// If one of the conversion functions is malformed, detect it immediately.
|
||||
panic(err)
|
||||
}
|
||||
}
|
33
pkg/client/clientcmd/api/v1/register.go
Normal file
33
pkg/client/clientcmd/api/v1/register.go
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
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 v1
|
||||
|
||||
import (
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
)
|
||||
|
||||
// Codec encodes internal objects to the v1 scheme
|
||||
var Codec = runtime.CodecFor(api.Scheme, "v1")
|
||||
|
||||
func init() {
|
||||
api.Scheme.AddKnownTypes("v1",
|
||||
&Config{},
|
||||
)
|
||||
}
|
||||
|
||||
func (*Config) IsAnAPIObject() {}
|
120
pkg/client/clientcmd/api/v1/types.go
Normal file
120
pkg/client/clientcmd/api/v1/types.go
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
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 v1
|
||||
|
||||
import (
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta3"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
)
|
||||
|
||||
// Where possible, json tags match the cli argument names.
|
||||
// Top level config objects and all values required for proper functioning are not "omitempty". Any truly optional piece of config is allowed to be omitted.
|
||||
|
||||
// Config holds the information needed to build connect to remote kubernetes clusters as a given user
|
||||
type Config struct {
|
||||
v1beta3.TypeMeta `json:",inline"`
|
||||
// Preferences holds general information to be use for cli interactions
|
||||
Preferences Preferences `json:"preferences"`
|
||||
// Clusters is a map of referencable names to cluster configs
|
||||
Clusters []NamedCluster `json:"clusters"`
|
||||
// AuthInfos is a map of referencable names to user configs
|
||||
AuthInfos []NamedAuthInfo `json:"users"`
|
||||
// Contexts is a map of referencable names to context configs
|
||||
Contexts []NamedContext `json:"contexts"`
|
||||
// CurrentContext is the name of the context that you would like to use by default
|
||||
CurrentContext string `json:"current-context"`
|
||||
// Extensions holds additional information. This is useful for extenders so that reads and writes don't clobber unknown fields
|
||||
Extensions []NamedExtension `json:"extensions,omitempty"`
|
||||
}
|
||||
|
||||
type Preferences struct {
|
||||
Colors bool `json:"colors,omitempty"`
|
||||
// Extensions holds additional information. This is useful for extenders so that reads and writes don't clobber unknown fields
|
||||
Extensions []NamedExtension `json:"extensions,omitempty"`
|
||||
}
|
||||
|
||||
// Cluster contains information about how to communicate with a kubernetes cluster
|
||||
type Cluster struct {
|
||||
// Server is the address of the kubernetes cluster (https://hostname:port).
|
||||
Server string `json:"server"`
|
||||
// APIVersion is the preferred api version for communicating with the kubernetes cluster (v1beta1, v1beta2, v1beta3, etc).
|
||||
APIVersion string `json:"api-version,omitempty"`
|
||||
// InsecureSkipTLSVerify skips the validity check for the server's certificate. This will make your HTTPS connections insecure.
|
||||
InsecureSkipTLSVerify bool `json:"insecure-skip-tls-verify,omitempty"`
|
||||
// CertificateAuthority is the path to a cert file for the certificate authority.
|
||||
CertificateAuthority string `json:"certificate-authority,omitempty"`
|
||||
// Extensions holds additional information. This is useful for extenders so that reads and writes don't clobber unknown fields
|
||||
Extensions []NamedExtension `json:"extensions,omitempty"`
|
||||
}
|
||||
|
||||
// AuthInfo contains information that describes identity information. This is use to tell the kubernetes cluster who you are.
|
||||
type AuthInfo struct {
|
||||
// AuthPath is the path to a kubernetes auth file (~/.kubernetes_auth). If you provide an AuthPath, the other options specified are ignored
|
||||
AuthPath string `json:"auth-path,omitempty"`
|
||||
// ClientCertificate is the path to a client cert file for TLS.
|
||||
ClientCertificate string `json:"client-certificate,omitempty"`
|
||||
// ClientKey is the path to a client key file for TLS.
|
||||
ClientKey string `json:"client-key,omitempty"`
|
||||
// Token is the bearer token for authentication to the kubernetes cluster.
|
||||
Token string `json:"token,omitempty"`
|
||||
// Extensions holds additional information. This is useful for extenders so that reads and writes don't clobber unknown fields
|
||||
Extensions []NamedExtension `json:"extensions,omitempty"`
|
||||
}
|
||||
|
||||
// Context is a tuple of references to a cluster (how do I communicate with a kubernetes cluster), a user (how do I identify myself), and a namespace (what subset of resources do I want to work with)
|
||||
type Context struct {
|
||||
// Cluster is the name of the cluster for this context
|
||||
Cluster string `json:"cluster"`
|
||||
// AuthInfo is the name of the authInfo for this context
|
||||
AuthInfo string `json:"user"`
|
||||
// Namespace is the default namespace to use on unspecified requests
|
||||
Namespace string `json:"namespace,omitempty"`
|
||||
// Extensions holds additional information. This is useful for extenders so that reads and writes don't clobber unknown fields
|
||||
Extensions []NamedExtension `json:"extensions,omitempty"`
|
||||
}
|
||||
|
||||
// NamedCluster relates nicknames to cluster information
|
||||
type NamedCluster struct {
|
||||
// Name is the nickname for this Cluster
|
||||
Name string `json:"name"`
|
||||
// Cluster holds the cluster information
|
||||
Cluster Cluster `json:"cluster"`
|
||||
}
|
||||
|
||||
// NamedContext relates nicknames to context information
|
||||
type NamedContext struct {
|
||||
// Name is the nickname for this Context
|
||||
Name string `json:"name"`
|
||||
// Context holds the context information
|
||||
Context Context `json:"context"`
|
||||
}
|
||||
|
||||
// NamedAuthInfo relates nicknames to auth information
|
||||
type NamedAuthInfo struct {
|
||||
// Name is the nickname for this AuthInfo
|
||||
Name string `json:"name"`
|
||||
// AuthInfo holds the auth information
|
||||
AuthInfo AuthInfo `json:"user"`
|
||||
}
|
||||
|
||||
// NamedExtension relates nicknames to extension information
|
||||
type NamedExtension struct {
|
||||
// Name is the nickname for this Extension
|
||||
Name string `json:"name"`
|
||||
// Extension holds the extension information
|
||||
Extension runtime.RawExtension `json:"extension"`
|
||||
}
|
@@ -23,45 +23,51 @@ import (
|
||||
"github.com/imdario/mergo"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
|
||||
clientcmdapi "github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/clientauth"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
// TODO: eventually apiserver should start on 443 and be secure by default
|
||||
defaultCluster = Cluster{Server: "http://localhost:8080"}
|
||||
envVarCluster = Cluster{Server: os.Getenv("KUBERNETES_MASTER")}
|
||||
defaultCluster = clientcmdapi.Cluster{Server: "http://localhost:8080"}
|
||||
envVarCluster = clientcmdapi.Cluster{Server: os.Getenv("KUBERNETES_MASTER")}
|
||||
)
|
||||
|
||||
// ClientConfig is used to make it easy to get an api server client
|
||||
type ClientConfig interface {
|
||||
RawConfig() (clientcmdapi.Config, error)
|
||||
// ClientConfig returns a complete client config
|
||||
ClientConfig() (*client.Config, error)
|
||||
}
|
||||
|
||||
// DirectClientConfig is a ClientConfig interface that is backed by a Config, options overrides, and an optional fallbackReader for auth information
|
||||
// DirectClientConfig is a ClientConfig interface that is backed by a clientcmdapi.Config, options overrides, and an optional fallbackReader for auth information
|
||||
type DirectClientConfig struct {
|
||||
config Config
|
||||
config clientcmdapi.Config
|
||||
contextName string
|
||||
overrides *ConfigOverrides
|
||||
fallbackReader io.Reader
|
||||
}
|
||||
|
||||
// NewDefaultClientConfig creates a DirectClientConfig using the config.CurrentContext as the context name
|
||||
func NewDefaultClientConfig(config Config, overrides *ConfigOverrides) ClientConfig {
|
||||
func NewDefaultClientConfig(config clientcmdapi.Config, overrides *ConfigOverrides) ClientConfig {
|
||||
return DirectClientConfig{config, config.CurrentContext, overrides, nil}
|
||||
}
|
||||
|
||||
// NewNonInteractiveClientConfig creates a DirectClientConfig using the passed context name and does not have a fallback reader for auth information
|
||||
func NewNonInteractiveClientConfig(config Config, contextName string, overrides *ConfigOverrides) ClientConfig {
|
||||
func NewNonInteractiveClientConfig(config clientcmdapi.Config, contextName string, overrides *ConfigOverrides) ClientConfig {
|
||||
return DirectClientConfig{config, contextName, overrides, nil}
|
||||
}
|
||||
|
||||
// NewInteractiveClientConfig creates a DirectClientConfig using the passed context name and a reader in case auth information is not provided via files or flags
|
||||
func NewInteractiveClientConfig(config Config, contextName string, overrides *ConfigOverrides, fallbackReader io.Reader) ClientConfig {
|
||||
func NewInteractiveClientConfig(config clientcmdapi.Config, contextName string, overrides *ConfigOverrides, fallbackReader io.Reader) ClientConfig {
|
||||
return DirectClientConfig{config, contextName, overrides, fallbackReader}
|
||||
}
|
||||
|
||||
func (config DirectClientConfig) RawConfig() (clientcmdapi.Config, error) {
|
||||
return config.config, nil
|
||||
}
|
||||
|
||||
// ClientConfig implements ClientConfig
|
||||
func (config DirectClientConfig) ClientConfig() (*client.Config, error) {
|
||||
if err := config.ConfirmUsable(); err != nil {
|
||||
@@ -102,7 +108,7 @@ func (config DirectClientConfig) ClientConfig() (*client.Config, error) {
|
||||
// 1. configClusterInfo (the final result of command line flags and merged .kubeconfig files)
|
||||
// 2. configAuthInfo.auth-path (this file can contain information that conflicts with #1, and we want #1 to win the priority)
|
||||
// 3. load the ~/.kubernetes_auth file as a default
|
||||
func getServerIdentificationPartialConfig(configAuthInfo AuthInfo, configClusterInfo Cluster) (*client.Config, error) {
|
||||
func getServerIdentificationPartialConfig(configAuthInfo clientcmdapi.AuthInfo, configClusterInfo clientcmdapi.Cluster) (*client.Config, error) {
|
||||
mergedConfig := &client.Config{}
|
||||
|
||||
defaultAuthPathInfo, err := NewDefaultAuthLoader().LoadAuth(os.Getenv("HOME") + "/.kubernetes_auth")
|
||||
@@ -140,7 +146,7 @@ func getServerIdentificationPartialConfig(configAuthInfo AuthInfo, configCluster
|
||||
// 2. configAuthInfo.auth-path (this file can contain information that conflicts with #1, and we want #1 to win the priority)
|
||||
// 3. if there is not enough information to idenfity the user, load try the ~/.kubernetes_auth file
|
||||
// 4. if there is not enough information to identify the user, prompt if possible
|
||||
func getUserIdentificationPartialConfig(configAuthInfo AuthInfo, fallbackReader io.Reader) (*client.Config, error) {
|
||||
func getUserIdentificationPartialConfig(configAuthInfo clientcmdapi.AuthInfo, fallbackReader io.Reader) (*client.Config, error) {
|
||||
mergedConfig := &client.Config{}
|
||||
|
||||
if len(configAuthInfo.AuthPath) > 0 {
|
||||
@@ -255,15 +261,15 @@ func (config DirectClientConfig) getClusterName() string {
|
||||
return config.getContext().Cluster
|
||||
}
|
||||
|
||||
func (config DirectClientConfig) getContext() Context {
|
||||
func (config DirectClientConfig) getContext() clientcmdapi.Context {
|
||||
return config.config.Contexts[config.getContextName()]
|
||||
}
|
||||
|
||||
func (config DirectClientConfig) getAuthInfo() AuthInfo {
|
||||
func (config DirectClientConfig) getAuthInfo() clientcmdapi.AuthInfo {
|
||||
authInfos := config.config.AuthInfos
|
||||
authInfoName := config.getAuthInfoName()
|
||||
|
||||
var mergedAuthInfo AuthInfo
|
||||
var mergedAuthInfo clientcmdapi.AuthInfo
|
||||
if configAuthInfo, exists := authInfos[authInfoName]; exists {
|
||||
mergo.Merge(&mergedAuthInfo, configAuthInfo)
|
||||
}
|
||||
@@ -272,11 +278,11 @@ func (config DirectClientConfig) getAuthInfo() AuthInfo {
|
||||
return mergedAuthInfo
|
||||
}
|
||||
|
||||
func (config DirectClientConfig) getCluster() Cluster {
|
||||
func (config DirectClientConfig) getCluster() clientcmdapi.Cluster {
|
||||
clusterInfos := config.config.Clusters
|
||||
clusterInfoName := config.getClusterName()
|
||||
|
||||
var mergedClusterInfo Cluster
|
||||
var mergedClusterInfo clientcmdapi.Cluster
|
||||
mergo.Merge(&mergedClusterInfo, defaultCluster)
|
||||
mergo.Merge(&mergedClusterInfo, envVarCluster)
|
||||
if configClusterInfo, exists := clusterInfos[clusterInfoName]; exists {
|
||||
|
@@ -22,23 +22,24 @@ import (
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
|
||||
clientcmdapi "github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd/api"
|
||||
)
|
||||
|
||||
func createValidTestConfig() *Config {
|
||||
func createValidTestConfig() *clientcmdapi.Config {
|
||||
const (
|
||||
server = "https://anything.com:8080"
|
||||
token = "the-token"
|
||||
)
|
||||
|
||||
config := NewConfig()
|
||||
config.Clusters["clean"] = Cluster{
|
||||
config := clientcmdapi.NewConfig()
|
||||
config.Clusters["clean"] = clientcmdapi.Cluster{
|
||||
Server: server,
|
||||
APIVersion: latest.Version,
|
||||
}
|
||||
config.AuthInfos["clean"] = AuthInfo{
|
||||
config.AuthInfos["clean"] = clientcmdapi.AuthInfo{
|
||||
Token: token,
|
||||
}
|
||||
config.Contexts["clean"] = Context{
|
||||
config.Contexts["clean"] = clientcmdapi.Context{
|
||||
Cluster: "clean",
|
||||
AuthInfo: "clean",
|
||||
}
|
||||
|
@@ -20,8 +20,11 @@ import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/imdario/mergo"
|
||||
"gopkg.in/v2/yaml"
|
||||
|
||||
clientcmdapi "github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd/api"
|
||||
clientcmdlatest "github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd/api/latest"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -56,8 +59,8 @@ func NewClientConfigLoadingRules() *ClientConfigLoadingRules {
|
||||
// This means that the first file to set CurrentContext will have its context preserved. It also means
|
||||
// that if two files specify a "red-user", only values from the first file's red-user are used. Even
|
||||
// non-conflicting entries from the second file's "red-user" are discarded.
|
||||
func (rules *ClientConfigLoadingRules) Load() (*Config, error) {
|
||||
config := NewConfig()
|
||||
func (rules *ClientConfigLoadingRules) Load() (*clientcmdapi.Config, error) {
|
||||
config := clientcmdapi.NewConfig()
|
||||
|
||||
mergeConfigWithFile(config, rules.CommandLinePath)
|
||||
mergeConfigWithFile(config, rules.EnvVarPath)
|
||||
@@ -67,7 +70,7 @@ func (rules *ClientConfigLoadingRules) Load() (*Config, error) {
|
||||
return config, nil
|
||||
}
|
||||
|
||||
func mergeConfigWithFile(startingConfig *Config, filename string) error {
|
||||
func mergeConfigWithFile(startingConfig *clientcmdapi.Config, filename string) error {
|
||||
if len(filename) == 0 {
|
||||
// no work to do
|
||||
return nil
|
||||
@@ -84,16 +87,15 @@ func mergeConfigWithFile(startingConfig *Config, filename string) error {
|
||||
}
|
||||
|
||||
// LoadFromFile takes a filename and deserializes the contents into Config object
|
||||
func LoadFromFile(filename string) (*Config, error) {
|
||||
config := &Config{}
|
||||
func LoadFromFile(filename string) (*clientcmdapi.Config, error) {
|
||||
config := &clientcmdapi.Config{}
|
||||
|
||||
kubeconfigBytes, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = yaml.Unmarshal(kubeconfigBytes, &config)
|
||||
if err != nil {
|
||||
if err := clientcmdlatest.Codec.DecodeInto(kubeconfigBytes, config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -102,16 +104,20 @@ func LoadFromFile(filename string) (*Config, error) {
|
||||
|
||||
// WriteToFile serializes the config to yaml and writes it out to a file. If no present, it creates the file with 0644. If it is present
|
||||
// it stomps the contents
|
||||
func WriteToFile(config Config, filename string) error {
|
||||
content, err := yaml.Marshal(config)
|
||||
func WriteToFile(config clientcmdapi.Config, filename string) error {
|
||||
json, err := clientcmdlatest.Codec.Encode(&config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = ioutil.WriteFile(filename, content, 0644)
|
||||
content, err := yaml.JSONToYAML(json)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := ioutil.WriteFile(filename, content, 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@@ -21,47 +21,50 @@ import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"gopkg.in/v2/yaml"
|
||||
"github.com/ghodss/yaml"
|
||||
|
||||
clientcmdapi "github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd/api"
|
||||
clientcmdlatest "github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd/api/latest"
|
||||
)
|
||||
|
||||
var (
|
||||
testConfigAlfa = Config{
|
||||
AuthInfos: map[string]AuthInfo{
|
||||
testConfigAlfa = clientcmdapi.Config{
|
||||
AuthInfos: map[string]clientcmdapi.AuthInfo{
|
||||
"red-user": {Token: "red-token"}},
|
||||
Clusters: map[string]Cluster{
|
||||
Clusters: map[string]clientcmdapi.Cluster{
|
||||
"cow-cluster": {Server: "http://cow.org:8080"}},
|
||||
Contexts: map[string]Context{
|
||||
Contexts: map[string]clientcmdapi.Context{
|
||||
"federal-context": {AuthInfo: "red-user", Cluster: "cow-cluster", Namespace: "hammer-ns"}},
|
||||
}
|
||||
testConfigBravo = Config{
|
||||
AuthInfos: map[string]AuthInfo{
|
||||
testConfigBravo = clientcmdapi.Config{
|
||||
AuthInfos: map[string]clientcmdapi.AuthInfo{
|
||||
"black-user": {Token: "black-token"}},
|
||||
Clusters: map[string]Cluster{
|
||||
Clusters: map[string]clientcmdapi.Cluster{
|
||||
"pig-cluster": {Server: "http://pig.org:8080"}},
|
||||
Contexts: map[string]Context{
|
||||
Contexts: map[string]clientcmdapi.Context{
|
||||
"queen-anne-context": {AuthInfo: "black-user", Cluster: "pig-cluster", Namespace: "saw-ns"}},
|
||||
}
|
||||
testConfigCharlie = Config{
|
||||
AuthInfos: map[string]AuthInfo{
|
||||
testConfigCharlie = clientcmdapi.Config{
|
||||
AuthInfos: map[string]clientcmdapi.AuthInfo{
|
||||
"green-user": {Token: "green-token"}},
|
||||
Clusters: map[string]Cluster{
|
||||
Clusters: map[string]clientcmdapi.Cluster{
|
||||
"horse-cluster": {Server: "http://horse.org:8080"}},
|
||||
Contexts: map[string]Context{
|
||||
Contexts: map[string]clientcmdapi.Context{
|
||||
"shaker-context": {AuthInfo: "green-user", Cluster: "horse-cluster", Namespace: "chisel-ns"}},
|
||||
}
|
||||
testConfigDelta = Config{
|
||||
AuthInfos: map[string]AuthInfo{
|
||||
testConfigDelta = clientcmdapi.Config{
|
||||
AuthInfos: map[string]clientcmdapi.AuthInfo{
|
||||
"blue-user": {Token: "blue-token"}},
|
||||
Clusters: map[string]Cluster{
|
||||
Clusters: map[string]clientcmdapi.Cluster{
|
||||
"chicken-cluster": {Server: "http://chicken.org:8080"}},
|
||||
Contexts: map[string]Context{
|
||||
Contexts: map[string]clientcmdapi.Context{
|
||||
"gothic-context": {AuthInfo: "blue-user", Cluster: "chicken-cluster", Namespace: "plane-ns"}},
|
||||
}
|
||||
testConfigConflictAlfa = Config{
|
||||
AuthInfos: map[string]AuthInfo{
|
||||
testConfigConflictAlfa = clientcmdapi.Config{
|
||||
AuthInfos: map[string]clientcmdapi.AuthInfo{
|
||||
"red-user": {Token: "a-different-red-token"},
|
||||
"yellow-user": {Token: "yellow-token"}},
|
||||
Clusters: map[string]Cluster{
|
||||
Clusters: map[string]clientcmdapi.Cluster{
|
||||
"cow-cluster": {Server: "http://a-different-cow.org:8080", InsecureSkipTLSVerify: true},
|
||||
"donkey-cluster": {Server: "http://donkey.org:8080", InsecureSkipTLSVerify: true}},
|
||||
CurrentContext: "federal-context",
|
||||
@@ -84,31 +87,42 @@ func ExampleMergingSomeWithConflict() {
|
||||
|
||||
mergedConfig, err := loadingRules.Load()
|
||||
|
||||
output, err := yaml.Marshal(mergedConfig)
|
||||
json, err := clientcmdlatest.Codec.Encode(mergedConfig)
|
||||
if err != nil {
|
||||
fmt.Printf("Unexpected error: %v", err)
|
||||
}
|
||||
output, err := yaml.JSONToYAML(json)
|
||||
if err != nil {
|
||||
fmt.Printf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
fmt.Printf("%v", string(output))
|
||||
// Output:
|
||||
// preferences: {}
|
||||
// apiVersion: v1
|
||||
// clusters:
|
||||
// cow-cluster:
|
||||
// - cluster:
|
||||
// server: http://cow.org:8080
|
||||
// donkey-cluster:
|
||||
// server: http://donkey.org:8080
|
||||
// name: cow-cluster
|
||||
// - cluster:
|
||||
// insecure-skip-tls-verify: true
|
||||
// users:
|
||||
// red-user:
|
||||
// token: red-token
|
||||
// yellow-user:
|
||||
// token: yellow-token
|
||||
// server: http://donkey.org:8080
|
||||
// name: donkey-cluster
|
||||
// contexts:
|
||||
// federal-context:
|
||||
// - context:
|
||||
// cluster: cow-cluster
|
||||
// user: red-user
|
||||
// namespace: hammer-ns
|
||||
// user: red-user
|
||||
// name: federal-context
|
||||
// current-context: federal-context
|
||||
// kind: Config
|
||||
// preferences: {}
|
||||
// users:
|
||||
// - name: red-user
|
||||
// user:
|
||||
// token: red-token
|
||||
// - name: yellow-user
|
||||
// user:
|
||||
// token: yellow-token
|
||||
}
|
||||
|
||||
func ExampleMergingEverythingNoConflicts() {
|
||||
@@ -135,48 +149,66 @@ func ExampleMergingEverythingNoConflicts() {
|
||||
|
||||
mergedConfig, err := loadingRules.Load()
|
||||
|
||||
output, err := yaml.Marshal(mergedConfig)
|
||||
json, err := clientcmdlatest.Codec.Encode(mergedConfig)
|
||||
if err != nil {
|
||||
fmt.Printf("Unexpected error: %v", err)
|
||||
}
|
||||
output, err := yaml.JSONToYAML(json)
|
||||
if err != nil {
|
||||
fmt.Printf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
fmt.Printf("%v", string(output))
|
||||
// Output:
|
||||
// preferences: {}
|
||||
// apiVersion: v1
|
||||
// clusters:
|
||||
// chicken-cluster:
|
||||
// - cluster:
|
||||
// server: http://chicken.org:8080
|
||||
// cow-cluster:
|
||||
// name: chicken-cluster
|
||||
// - cluster:
|
||||
// server: http://cow.org:8080
|
||||
// horse-cluster:
|
||||
// name: cow-cluster
|
||||
// - cluster:
|
||||
// server: http://horse.org:8080
|
||||
// pig-cluster:
|
||||
// name: horse-cluster
|
||||
// - cluster:
|
||||
// server: http://pig.org:8080
|
||||
// users:
|
||||
// black-user:
|
||||
// token: black-token
|
||||
// blue-user:
|
||||
// token: blue-token
|
||||
// green-user:
|
||||
// token: green-token
|
||||
// red-user:
|
||||
// token: red-token
|
||||
// name: pig-cluster
|
||||
// contexts:
|
||||
// federal-context:
|
||||
// - context:
|
||||
// cluster: cow-cluster
|
||||
// user: red-user
|
||||
// namespace: hammer-ns
|
||||
// gothic-context:
|
||||
// user: red-user
|
||||
// name: federal-context
|
||||
// - context:
|
||||
// cluster: chicken-cluster
|
||||
// user: blue-user
|
||||
// namespace: plane-ns
|
||||
// queen-anne-context:
|
||||
// user: blue-user
|
||||
// name: gothic-context
|
||||
// - context:
|
||||
// cluster: pig-cluster
|
||||
// user: black-user
|
||||
// namespace: saw-ns
|
||||
// shaker-context:
|
||||
// user: black-user
|
||||
// name: queen-anne-context
|
||||
// - context:
|
||||
// cluster: horse-cluster
|
||||
// user: green-user
|
||||
// namespace: chisel-ns
|
||||
// user: green-user
|
||||
// name: shaker-context
|
||||
// current-context: ""
|
||||
// kind: Config
|
||||
// preferences: {}
|
||||
// users:
|
||||
// - name: black-user
|
||||
// user:
|
||||
// token: black-token
|
||||
// - name: blue-user
|
||||
// user:
|
||||
// token: blue-token
|
||||
// - name: green-user
|
||||
// user:
|
||||
// token: green-token
|
||||
// - name: red-user
|
||||
// user:
|
||||
// token: red-token
|
||||
}
|
||||
|
@@ -20,6 +20,7 @@ import (
|
||||
"io"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
|
||||
clientcmdapi "github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd/api"
|
||||
)
|
||||
|
||||
// DeferredLoadingClientConfig is a ClientConfig interface that is backed by a set of loading rules
|
||||
@@ -59,6 +60,15 @@ func (config DeferredLoadingClientConfig) createClientConfig() (ClientConfig, er
|
||||
return mergedClientConfig, nil
|
||||
}
|
||||
|
||||
func (config DeferredLoadingClientConfig) RawConfig() (clientcmdapi.Config, error) {
|
||||
mergedConfig, err := config.createClientConfig()
|
||||
if err != nil {
|
||||
return clientcmdapi.Config{}, err
|
||||
}
|
||||
|
||||
return mergedConfig.RawConfig()
|
||||
}
|
||||
|
||||
// ClientConfig implements ClientConfig
|
||||
func (config DeferredLoadingClientConfig) ClientConfig() (*client.Config, error) {
|
||||
mergedClientConfig, err := config.createClientConfig()
|
||||
|
@@ -85,7 +85,7 @@ func testBindClientConfig(cmd *cobra.Command) ClientConfig {
|
||||
cmd.PersistentFlags().StringVar(&loadingRules.CommandLinePath, "kubeconfig", "", "Path to the kubeconfig file to use for CLI requests.")
|
||||
|
||||
overrides := &ConfigOverrides{}
|
||||
overrides.BindFlags(cmd.PersistentFlags(), RecommendedConfigOverrideFlags(""))
|
||||
BindOverrideFlags(overrides, cmd.PersistentFlags(), RecommendedConfigOverrideFlags(""))
|
||||
clientConfig := NewInteractiveDeferredLoadingClientConfig(loadingRules, overrides, os.Stdin)
|
||||
|
||||
return clientConfig
|
||||
|
@@ -18,13 +18,15 @@ package clientcmd
|
||||
|
||||
import (
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
clientcmdapi "github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd/api"
|
||||
)
|
||||
|
||||
// ConfigOverrides holds values that should override whatever information is pulled from the actual Config object. You can't
|
||||
// simply use an actual Config object, because Configs hold maps, but overrides are restricted to "at most one"
|
||||
type ConfigOverrides struct {
|
||||
AuthInfo AuthInfo
|
||||
ClusterInfo Cluster
|
||||
AuthInfo clientcmdapi.AuthInfo
|
||||
ClusterInfo clientcmdapi.Cluster
|
||||
Namespace string
|
||||
CurrentContext string
|
||||
ClusterName string
|
||||
@@ -105,8 +107,8 @@ func RecommendedConfigOverrideFlags(prefix string) ConfigOverrideFlags {
|
||||
}
|
||||
}
|
||||
|
||||
// BindFlags is a convenience method to bind the specified flags to their associated variables
|
||||
func (authInfo *AuthInfo) BindFlags(flags *pflag.FlagSet, flagNames AuthOverrideFlags) {
|
||||
// BindAuthInfoFlags is a convenience method to bind the specified flags to their associated variables
|
||||
func BindAuthInfoFlags(authInfo *clientcmdapi.AuthInfo, flags *pflag.FlagSet, flagNames AuthOverrideFlags) {
|
||||
// TODO short flag names are impossible to prefix, decide whether to keep them or not
|
||||
flags.StringVarP(&authInfo.AuthPath, flagNames.AuthPath, "a", "", "Path to the auth info file. If missing, prompt the user. Only used if using https.")
|
||||
flags.StringVar(&authInfo.ClientCertificate, flagNames.ClientCertificate, "", "Path to a client key file for TLS.")
|
||||
@@ -114,8 +116,8 @@ func (authInfo *AuthInfo) BindFlags(flags *pflag.FlagSet, flagNames AuthOverride
|
||||
flags.StringVar(&authInfo.Token, flagNames.Token, "", "Bearer token for authentication to the API server.")
|
||||
}
|
||||
|
||||
// BindFlags is a convenience method to bind the specified flags to their associated variables
|
||||
func (clusterInfo *Cluster) BindFlags(flags *pflag.FlagSet, flagNames ClusterOverrideFlags) {
|
||||
// BindClusterFlags is a convenience method to bind the specified flags to their associated variables
|
||||
func BindClusterFlags(clusterInfo *clientcmdapi.Cluster, flags *pflag.FlagSet, flagNames ClusterOverrideFlags) {
|
||||
// TODO short flag names are impossible to prefix, decide whether to keep them or not
|
||||
flags.StringVarP(&clusterInfo.Server, flagNames.APIServer, "s", "", "The address of the Kubernetes API server")
|
||||
flags.StringVar(&clusterInfo.APIVersion, flagNames.APIVersion, "", "The API version to use when talking to the server")
|
||||
@@ -123,10 +125,10 @@ func (clusterInfo *Cluster) BindFlags(flags *pflag.FlagSet, flagNames ClusterOve
|
||||
flags.BoolVar(&clusterInfo.InsecureSkipTLSVerify, flagNames.InsecureSkipTLSVerify, false, "If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure.")
|
||||
}
|
||||
|
||||
// BindFlags is a convenience method to bind the specified flags to their associated variables
|
||||
func (overrides *ConfigOverrides) BindFlags(flags *pflag.FlagSet, flagNames ConfigOverrideFlags) {
|
||||
(&overrides.AuthInfo).BindFlags(flags, flagNames.AuthOverrideFlags)
|
||||
(&overrides.ClusterInfo).BindFlags(flags, flagNames.ClusterOverrideFlags)
|
||||
// BindOverrideFlags is a convenience method to bind the specified flags to their associated variables
|
||||
func BindOverrideFlags(overrides *ConfigOverrides, flags *pflag.FlagSet, flagNames ConfigOverrideFlags) {
|
||||
BindAuthInfoFlags(&overrides.AuthInfo, flags, flagNames.AuthOverrideFlags)
|
||||
BindClusterFlags(&overrides.ClusterInfo, flags, flagNames.ClusterOverrideFlags)
|
||||
// TODO not integrated yet
|
||||
// flags.StringVar(&overrides.Namespace, flagNames.Namespace, "", "If present, the namespace scope for this CLI request.")
|
||||
flags.StringVar(&overrides.CurrentContext, flagNames.CurrentContext, "", "The name of the kubeconfig context to use")
|
||||
|
@@ -1,83 +0,0 @@
|
||||
/*
|
||||
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 clientcmd
|
||||
|
||||
import ()
|
||||
|
||||
// Where possible, yaml tags match the cli argument names.
|
||||
// Top level config objects and all values required for proper functioning are not "omitempty". Any truly optional piece of config is allowed to be omitted.
|
||||
|
||||
// Config holds the information needed to build connect to remote kubernetes clusters as a given user
|
||||
type Config struct {
|
||||
// Preferences holds general information to be use for cli interactions
|
||||
Preferences Preferences `yaml:"preferences"`
|
||||
// Clusters is a map of referencable names to cluster configs
|
||||
Clusters map[string]Cluster `yaml:"clusters"`
|
||||
// AuthInfos is a map of referencable names to user configs
|
||||
AuthInfos map[string]AuthInfo `yaml:"users"`
|
||||
// Contexts is a map of referencable names to context configs
|
||||
Contexts map[string]Context `yaml:"contexts"`
|
||||
// CurrentContext is the name of the context that you would like to use by default
|
||||
CurrentContext string `yaml:"current-context"`
|
||||
}
|
||||
|
||||
type Preferences struct {
|
||||
Colors bool `yaml:"colors,omitempty"`
|
||||
}
|
||||
|
||||
// Cluster contains information about how to communicate with a kubernetes cluster
|
||||
type Cluster struct {
|
||||
// Server is the address of the kubernetes cluster (https://hostname:port).
|
||||
Server string `yaml:"server"`
|
||||
// APIVersion is the preferred api version for communicating with the kubernetes cluster (v1beta1, v1beta2, v1beta3, etc).
|
||||
APIVersion string `yaml:"api-version,omitempty"`
|
||||
// InsecureSkipTLSVerify skips the validity check for the server's certificate. This will make your HTTPS connections insecure.
|
||||
InsecureSkipTLSVerify bool `yaml:"insecure-skip-tls-verify,omitempty"`
|
||||
// CertificateAuthority is the path to a cert file for the certificate authority.
|
||||
CertificateAuthority string `yaml:"certificate-authority,omitempty"`
|
||||
}
|
||||
|
||||
// AuthInfo contains information that describes identity information. This is use to tell the kubernetes cluster who you are.
|
||||
type AuthInfo struct {
|
||||
// AuthPath is the path to a kubernetes auth file (~/.kubernetes_auth). If you provide an AuthPath, the other options specified are ignored
|
||||
AuthPath string `yaml:"auth-path,omitempty"`
|
||||
// ClientCertificate is the path to a client cert file for TLS.
|
||||
ClientCertificate string `yaml:"client-certificate,omitempty"`
|
||||
// ClientKey is the path to a client key file for TLS.
|
||||
ClientKey string `yaml:"client-key,omitempty"`
|
||||
// Token is the bearer token for authentication to the kubernetes cluster.
|
||||
Token string `yaml:"token,omitempty"`
|
||||
}
|
||||
|
||||
// Context is a tuple of references to a cluster (how do I communicate with a kubernetes cluster), a user (how do I identify myself), and a namespace (what subset of resources do I want to work with)
|
||||
type Context struct {
|
||||
// Cluster is the name of the cluster for this context
|
||||
Cluster string `yaml:"cluster"`
|
||||
// AuthInfo is the name of the authInfo for this context
|
||||
AuthInfo string `yaml:"user"`
|
||||
// Namespace is the default namespace to use on unspecified requests
|
||||
Namespace string `yaml:"namespace,omitempty"`
|
||||
}
|
||||
|
||||
// NewConfig is a convenience function that returns a new Config object with non-nil maps
|
||||
func NewConfig() *Config {
|
||||
return &Config{
|
||||
Clusters: make(map[string]Cluster),
|
||||
AuthInfos: make(map[string]AuthInfo),
|
||||
Contexts: make(map[string]Context),
|
||||
}
|
||||
}
|
@@ -22,6 +22,7 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
clientcmdapi "github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||
utilerrors "github.com/GoogleCloudPlatform/kubernetes/pkg/util/errors"
|
||||
)
|
||||
@@ -47,7 +48,7 @@ func IsContextNotFound(err error) bool {
|
||||
}
|
||||
|
||||
// Validate checks for errors in the Config. It does not return early so that it can find as many errors as possible.
|
||||
func Validate(config Config) error {
|
||||
func Validate(config clientcmdapi.Config) error {
|
||||
validationErrors := make([]error, 0)
|
||||
|
||||
if len(config.CurrentContext) != 0 {
|
||||
@@ -73,7 +74,7 @@ func Validate(config Config) error {
|
||||
|
||||
// ConfirmUsable looks a particular context and determines if that particular part of the config is useable. There might still be errors in the config,
|
||||
// but no errors in the sections requested or referenced. It does not return early so that it can find as many errors as possible.
|
||||
func ConfirmUsable(config Config, passedContextName string) error {
|
||||
func ConfirmUsable(config clientcmdapi.Config, passedContextName string) error {
|
||||
validationErrors := make([]error, 0)
|
||||
|
||||
var contextName string
|
||||
@@ -102,7 +103,7 @@ func ConfirmUsable(config Config, passedContextName string) error {
|
||||
}
|
||||
|
||||
// validateClusterInfo looks for conflicts and errors in the cluster info
|
||||
func validateClusterInfo(clusterName string, clusterInfo Cluster) []error {
|
||||
func validateClusterInfo(clusterName string, clusterInfo clientcmdapi.Cluster) []error {
|
||||
validationErrors := make([]error, 0)
|
||||
|
||||
if len(clusterInfo.Server) == 0 {
|
||||
@@ -120,7 +121,7 @@ func validateClusterInfo(clusterName string, clusterInfo Cluster) []error {
|
||||
}
|
||||
|
||||
// validateAuthInfo looks for conflicts and errors in the auth info
|
||||
func validateAuthInfo(authInfoName string, authInfo AuthInfo) []error {
|
||||
func validateAuthInfo(authInfoName string, authInfo clientcmdapi.AuthInfo) []error {
|
||||
validationErrors := make([]error, 0)
|
||||
|
||||
usingAuthPath := false
|
||||
@@ -163,7 +164,7 @@ func validateAuthInfo(authInfoName string, authInfo AuthInfo) []error {
|
||||
}
|
||||
|
||||
// validateContext looks for errors in the context. It is not transitive, so errors in the reference authInfo or cluster configs are not included in this return
|
||||
func validateContext(contextName string, context Context, config Config) []error {
|
||||
func validateContext(contextName string, context clientcmdapi.Context, config clientcmdapi.Config) []error {
|
||||
validationErrors := make([]error, 0)
|
||||
|
||||
if len(context.AuthInfo) == 0 {
|
||||
|
@@ -22,30 +22,31 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
clientcmdapi "github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util/errors"
|
||||
)
|
||||
|
||||
func TestConfirmUsableBadInfoButOkConfig(t *testing.T) {
|
||||
config := NewConfig()
|
||||
config.Clusters["missing ca"] = Cluster{
|
||||
config := clientcmdapi.NewConfig()
|
||||
config.Clusters["missing ca"] = clientcmdapi.Cluster{
|
||||
Server: "anything",
|
||||
CertificateAuthority: "missing",
|
||||
}
|
||||
config.AuthInfos["error"] = AuthInfo{
|
||||
config.AuthInfos["error"] = clientcmdapi.AuthInfo{
|
||||
AuthPath: "anything",
|
||||
Token: "here",
|
||||
}
|
||||
config.Contexts["dirty"] = Context{
|
||||
config.Contexts["dirty"] = clientcmdapi.Context{
|
||||
Cluster: "missing ca",
|
||||
AuthInfo: "error",
|
||||
}
|
||||
config.Clusters["clean"] = Cluster{
|
||||
config.Clusters["clean"] = clientcmdapi.Cluster{
|
||||
Server: "anything",
|
||||
}
|
||||
config.AuthInfos["clean"] = AuthInfo{
|
||||
config.AuthInfos["clean"] = clientcmdapi.AuthInfo{
|
||||
Token: "here",
|
||||
}
|
||||
config.Contexts["clean"] = Context{
|
||||
config.Contexts["clean"] = clientcmdapi.Context{
|
||||
Cluster: "clean",
|
||||
AuthInfo: "clean",
|
||||
}
|
||||
@@ -62,16 +63,16 @@ func TestConfirmUsableBadInfoButOkConfig(t *testing.T) {
|
||||
badValidation.testConfig(t)
|
||||
}
|
||||
func TestConfirmUsableBadInfoConfig(t *testing.T) {
|
||||
config := NewConfig()
|
||||
config.Clusters["missing ca"] = Cluster{
|
||||
config := clientcmdapi.NewConfig()
|
||||
config.Clusters["missing ca"] = clientcmdapi.Cluster{
|
||||
Server: "anything",
|
||||
CertificateAuthority: "missing",
|
||||
}
|
||||
config.AuthInfos["error"] = AuthInfo{
|
||||
config.AuthInfos["error"] = clientcmdapi.AuthInfo{
|
||||
AuthPath: "anything",
|
||||
Token: "here",
|
||||
}
|
||||
config.Contexts["first"] = Context{
|
||||
config.Contexts["first"] = clientcmdapi.Context{
|
||||
Cluster: "missing ca",
|
||||
AuthInfo: "error",
|
||||
}
|
||||
@@ -83,7 +84,7 @@ func TestConfirmUsableBadInfoConfig(t *testing.T) {
|
||||
test.testConfirmUsable("first", t)
|
||||
}
|
||||
func TestConfirmUsableEmptyConfig(t *testing.T) {
|
||||
config := NewConfig()
|
||||
config := clientcmdapi.NewConfig()
|
||||
test := configValidationTest{
|
||||
config: config,
|
||||
expectedErrorSubstring: []string{"no context chosen"},
|
||||
@@ -92,7 +93,7 @@ func TestConfirmUsableEmptyConfig(t *testing.T) {
|
||||
test.testConfirmUsable("", t)
|
||||
}
|
||||
func TestConfirmUsableMissingConfig(t *testing.T) {
|
||||
config := NewConfig()
|
||||
config := clientcmdapi.NewConfig()
|
||||
test := configValidationTest{
|
||||
config: config,
|
||||
expectedErrorSubstring: []string{"context was not found for"},
|
||||
@@ -101,7 +102,7 @@ func TestConfirmUsableMissingConfig(t *testing.T) {
|
||||
test.testConfirmUsable("not-here", t)
|
||||
}
|
||||
func TestValidateEmptyConfig(t *testing.T) {
|
||||
config := NewConfig()
|
||||
config := clientcmdapi.NewConfig()
|
||||
test := configValidationTest{
|
||||
config: config,
|
||||
}
|
||||
@@ -109,7 +110,7 @@ func TestValidateEmptyConfig(t *testing.T) {
|
||||
test.testConfig(t)
|
||||
}
|
||||
func TestValidateMissingCurrentContextConfig(t *testing.T) {
|
||||
config := NewConfig()
|
||||
config := clientcmdapi.NewConfig()
|
||||
config.CurrentContext = "anything"
|
||||
test := configValidationTest{
|
||||
config: config,
|
||||
@@ -119,7 +120,7 @@ func TestValidateMissingCurrentContextConfig(t *testing.T) {
|
||||
test.testConfig(t)
|
||||
}
|
||||
func TestIsContextNotFound(t *testing.T) {
|
||||
config := NewConfig()
|
||||
config := clientcmdapi.NewConfig()
|
||||
config.CurrentContext = "anything"
|
||||
|
||||
err := Validate(*config)
|
||||
@@ -128,9 +129,9 @@ func TestIsContextNotFound(t *testing.T) {
|
||||
}
|
||||
}
|
||||
func TestValidateMissingReferencesConfig(t *testing.T) {
|
||||
config := NewConfig()
|
||||
config := clientcmdapi.NewConfig()
|
||||
config.CurrentContext = "anything"
|
||||
config.Contexts["anything"] = Context{Cluster: "missing", AuthInfo: "missing"}
|
||||
config.Contexts["anything"] = clientcmdapi.Context{Cluster: "missing", AuthInfo: "missing"}
|
||||
test := configValidationTest{
|
||||
config: config,
|
||||
expectedErrorSubstring: []string{"user, missing, was not found for Context anything", "cluster, missing, was not found for Context anything"},
|
||||
@@ -140,9 +141,9 @@ func TestValidateMissingReferencesConfig(t *testing.T) {
|
||||
test.testConfig(t)
|
||||
}
|
||||
func TestValidateEmptyContext(t *testing.T) {
|
||||
config := NewConfig()
|
||||
config := clientcmdapi.NewConfig()
|
||||
config.CurrentContext = "anything"
|
||||
config.Contexts["anything"] = Context{}
|
||||
config.Contexts["anything"] = clientcmdapi.Context{}
|
||||
test := configValidationTest{
|
||||
config: config,
|
||||
expectedErrorSubstring: []string{"user was not specified for Context anything", "cluster was not specified for Context anything"},
|
||||
@@ -153,8 +154,8 @@ func TestValidateEmptyContext(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidateEmptyClusterInfo(t *testing.T) {
|
||||
config := NewConfig()
|
||||
config.Clusters["empty"] = Cluster{}
|
||||
config := clientcmdapi.NewConfig()
|
||||
config.Clusters["empty"] = clientcmdapi.Cluster{}
|
||||
test := configValidationTest{
|
||||
config: config,
|
||||
expectedErrorSubstring: []string{"no server found for"},
|
||||
@@ -164,8 +165,8 @@ func TestValidateEmptyClusterInfo(t *testing.T) {
|
||||
test.testConfig(t)
|
||||
}
|
||||
func TestValidateMissingCAFileClusterInfo(t *testing.T) {
|
||||
config := NewConfig()
|
||||
config.Clusters["missing ca"] = Cluster{
|
||||
config := clientcmdapi.NewConfig()
|
||||
config.Clusters["missing ca"] = clientcmdapi.Cluster{
|
||||
Server: "anything",
|
||||
CertificateAuthority: "missing",
|
||||
}
|
||||
@@ -178,8 +179,8 @@ func TestValidateMissingCAFileClusterInfo(t *testing.T) {
|
||||
test.testConfig(t)
|
||||
}
|
||||
func TestValidateCleanClusterInfo(t *testing.T) {
|
||||
config := NewConfig()
|
||||
config.Clusters["clean"] = Cluster{
|
||||
config := clientcmdapi.NewConfig()
|
||||
config.Clusters["clean"] = clientcmdapi.Cluster{
|
||||
Server: "anything",
|
||||
}
|
||||
test := configValidationTest{
|
||||
@@ -193,8 +194,8 @@ func TestValidateCleanWithCAClusterInfo(t *testing.T) {
|
||||
tempFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(tempFile.Name())
|
||||
|
||||
config := NewConfig()
|
||||
config.Clusters["clean"] = Cluster{
|
||||
config := clientcmdapi.NewConfig()
|
||||
config.Clusters["clean"] = clientcmdapi.Cluster{
|
||||
Server: "anything",
|
||||
CertificateAuthority: tempFile.Name(),
|
||||
}
|
||||
@@ -207,8 +208,8 @@ func TestValidateCleanWithCAClusterInfo(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidateEmptyAuthInfo(t *testing.T) {
|
||||
config := NewConfig()
|
||||
config.AuthInfos["error"] = AuthInfo{}
|
||||
config := clientcmdapi.NewConfig()
|
||||
config.AuthInfos["error"] = clientcmdapi.AuthInfo{}
|
||||
test := configValidationTest{
|
||||
config: config,
|
||||
}
|
||||
@@ -217,8 +218,8 @@ func TestValidateEmptyAuthInfo(t *testing.T) {
|
||||
test.testConfig(t)
|
||||
}
|
||||
func TestValidatePathNotFoundAuthInfo(t *testing.T) {
|
||||
config := NewConfig()
|
||||
config.AuthInfos["error"] = AuthInfo{
|
||||
config := clientcmdapi.NewConfig()
|
||||
config.AuthInfos["error"] = clientcmdapi.AuthInfo{
|
||||
AuthPath: "missing",
|
||||
}
|
||||
test := configValidationTest{
|
||||
@@ -230,8 +231,8 @@ func TestValidatePathNotFoundAuthInfo(t *testing.T) {
|
||||
test.testConfig(t)
|
||||
}
|
||||
func TestValidateCertFilesNotFoundAuthInfo(t *testing.T) {
|
||||
config := NewConfig()
|
||||
config.AuthInfos["error"] = AuthInfo{
|
||||
config := clientcmdapi.NewConfig()
|
||||
config.AuthInfos["error"] = clientcmdapi.AuthInfo{
|
||||
ClientCertificate: "missing",
|
||||
ClientKey: "missing",
|
||||
}
|
||||
@@ -247,8 +248,8 @@ func TestValidateCleanCertFilesAuthInfo(t *testing.T) {
|
||||
tempFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(tempFile.Name())
|
||||
|
||||
config := NewConfig()
|
||||
config.AuthInfos["clean"] = AuthInfo{
|
||||
config := clientcmdapi.NewConfig()
|
||||
config.AuthInfos["clean"] = clientcmdapi.AuthInfo{
|
||||
ClientCertificate: tempFile.Name(),
|
||||
ClientKey: tempFile.Name(),
|
||||
}
|
||||
@@ -263,8 +264,8 @@ func TestValidateCleanPathAuthInfo(t *testing.T) {
|
||||
tempFile, _ := ioutil.TempFile("", "")
|
||||
defer os.Remove(tempFile.Name())
|
||||
|
||||
config := NewConfig()
|
||||
config.AuthInfos["clean"] = AuthInfo{
|
||||
config := clientcmdapi.NewConfig()
|
||||
config.AuthInfos["clean"] = clientcmdapi.AuthInfo{
|
||||
AuthPath: tempFile.Name(),
|
||||
}
|
||||
test := configValidationTest{
|
||||
@@ -275,8 +276,8 @@ func TestValidateCleanPathAuthInfo(t *testing.T) {
|
||||
test.testConfig(t)
|
||||
}
|
||||
func TestValidateCleanTokenAuthInfo(t *testing.T) {
|
||||
config := NewConfig()
|
||||
config.AuthInfos["clean"] = AuthInfo{
|
||||
config := clientcmdapi.NewConfig()
|
||||
config.AuthInfos["clean"] = clientcmdapi.AuthInfo{
|
||||
Token: "any-value",
|
||||
}
|
||||
test := configValidationTest{
|
||||
@@ -288,7 +289,7 @@ func TestValidateCleanTokenAuthInfo(t *testing.T) {
|
||||
}
|
||||
|
||||
type configValidationTest struct {
|
||||
config *Config
|
||||
config *clientcmdapi.Config
|
||||
expectedErrorSubstring []string
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user