Replace godep with dep
This commit is contained in:
parent
1e7489927c
commit
bf5616c65b
14883 changed files with 3937406 additions and 361781 deletions
54
vendor/k8s.io/kubernetes/cmd/kubeadm/app/BUILD
generated
vendored
Normal file
54
vendor/k8s.io/kubernetes/cmd/kubeadm/app/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["kubeadm.go"],
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/apis/kubeadm/install:go_default_library",
|
||||
"//cmd/kubeadm/app/cmd:go_default_library",
|
||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//cmd/kubeadm/app/apis/kubeadm:all-srcs",
|
||||
"//cmd/kubeadm/app/cmd:all-srcs",
|
||||
"//cmd/kubeadm/app/constants:all-srcs",
|
||||
"//cmd/kubeadm/app/discovery:all-srcs",
|
||||
"//cmd/kubeadm/app/features:all-srcs",
|
||||
"//cmd/kubeadm/app/images:all-srcs",
|
||||
"//cmd/kubeadm/app/node:all-srcs",
|
||||
"//cmd/kubeadm/app/phases/addons/dns:all-srcs",
|
||||
"//cmd/kubeadm/app/phases/addons/proxy:all-srcs",
|
||||
"//cmd/kubeadm/app/phases/apiconfig:all-srcs",
|
||||
"//cmd/kubeadm/app/phases/bootstraptoken/clusterinfo:all-srcs",
|
||||
"//cmd/kubeadm/app/phases/bootstraptoken/node:all-srcs",
|
||||
"//cmd/kubeadm/app/phases/certs:all-srcs",
|
||||
"//cmd/kubeadm/app/phases/controlplane:all-srcs",
|
||||
"//cmd/kubeadm/app/phases/etcd:all-srcs",
|
||||
"//cmd/kubeadm/app/phases/kubeconfig:all-srcs",
|
||||
"//cmd/kubeadm/app/phases/markmaster:all-srcs",
|
||||
"//cmd/kubeadm/app/phases/selfhosting:all-srcs",
|
||||
"//cmd/kubeadm/app/phases/token:all-srcs",
|
||||
"//cmd/kubeadm/app/phases/upgrade:all-srcs",
|
||||
"//cmd/kubeadm/app/phases/uploadconfig:all-srcs",
|
||||
"//cmd/kubeadm/app/preflight:all-srcs",
|
||||
"//cmd/kubeadm/app/util:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
42
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/BUILD
generated
vendored
Normal file
42
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"doc.go",
|
||||
"register.go",
|
||||
"types.go",
|
||||
"well_known_labels.go",
|
||||
"zz_generated.deepcopy.go",
|
||||
],
|
||||
deps = [
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/conversion:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//cmd/kubeadm/app/apis/kubeadm/fuzzer:all-srcs",
|
||||
"//cmd/kubeadm/app/apis/kubeadm/install:all-srcs",
|
||||
"//cmd/kubeadm/app/apis/kubeadm/v1alpha1:all-srcs",
|
||||
"//cmd/kubeadm/app/apis/kubeadm/validation:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
19
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/doc.go
generated
vendored
Normal file
19
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
// +k8s:deepcopy-gen=package,register
|
||||
// +groupName=kubeadm.k8s.io
|
||||
package kubeadm // import "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
29
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/fuzzer/BUILD
generated
vendored
Normal file
29
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/fuzzer/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["fuzzer.go"],
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||
"//vendor/github.com/google/gofuzz:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
58
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/fuzzer/fuzzer.go
generated
vendored
Normal file
58
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/fuzzer/fuzzer.go
generated
vendored
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
Copyright 2017 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 fuzzer
|
||||
|
||||
import (
|
||||
"github.com/google/gofuzz"
|
||||
|
||||
runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
)
|
||||
|
||||
// Funcs returns the fuzzer functions for the kubeadm apis.
|
||||
func Funcs(codecs runtimeserializer.CodecFactory) []interface{} {
|
||||
return []interface{}{
|
||||
func(obj *kubeadm.MasterConfiguration, c fuzz.Continue) {
|
||||
c.FuzzNoCustom(obj)
|
||||
obj.KubernetesVersion = "v10"
|
||||
obj.API.BindPort = 20
|
||||
obj.API.AdvertiseAddress = "foo"
|
||||
obj.Networking.ServiceSubnet = "foo"
|
||||
obj.Networking.DNSDomain = "foo"
|
||||
obj.AuthorizationModes = []string{"foo"}
|
||||
obj.CertificatesDir = "foo"
|
||||
obj.APIServerCertSANs = []string{}
|
||||
obj.Token = "foo"
|
||||
obj.Etcd.Image = "foo"
|
||||
obj.Etcd.DataDir = "foo"
|
||||
obj.ImageRepository = "foo"
|
||||
obj.CIImageRepository = ""
|
||||
obj.UnifiedControlPlaneImage = "foo"
|
||||
obj.FeatureGates = map[string]bool{}
|
||||
},
|
||||
func(obj *kubeadm.NodeConfiguration, c fuzz.Continue) {
|
||||
c.FuzzNoCustom(obj)
|
||||
obj.CACertPath = "foo"
|
||||
obj.CACertPath = "foo"
|
||||
obj.DiscoveryFile = "foo"
|
||||
obj.DiscoveryToken = "foo"
|
||||
obj.DiscoveryTokenAPIServers = []string{"foo"}
|
||||
obj.TLSBootstrapToken = "foo"
|
||||
obj.Token = "foo"
|
||||
},
|
||||
}
|
||||
}
|
||||
46
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/install/BUILD
generated
vendored
Normal file
46
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/install/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"doc.go",
|
||||
"install.go",
|
||||
],
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||
"//cmd/kubeadm/app/apis/kubeadm/v1alpha1:go_default_library",
|
||||
"//pkg/api:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apimachinery/announced:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apimachinery/registered:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["install_test.go"],
|
||||
library = ":go_default_library",
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/apis/kubeadm/fuzzer:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/testing/roundtrip:go_default_library",
|
||||
],
|
||||
)
|
||||
17
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/install/doc.go
generated
vendored
Normal file
17
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/install/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
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 install // import "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/install"
|
||||
46
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/install/install.go
generated
vendored
Normal file
46
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/install/install.go
generated
vendored
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
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 install
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/apimachinery/announced"
|
||||
"k8s.io/apimachinery/pkg/apimachinery/registered"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
)
|
||||
|
||||
func init() {
|
||||
Install(api.GroupFactoryRegistry, api.Registry, api.Scheme)
|
||||
}
|
||||
|
||||
// Install registers the API group and adds types to a scheme
|
||||
func Install(groupFactoryRegistry announced.APIGroupFactoryRegistry, registry *registered.APIRegistrationManager, scheme *runtime.Scheme) {
|
||||
if err := announced.NewGroupMetaFactory(
|
||||
&announced.GroupMetaFactoryArgs{
|
||||
GroupName: kubeadm.GroupName,
|
||||
VersionPreferenceOrder: []string{v1alpha1.SchemeGroupVersion.Version},
|
||||
AddInternalObjectsToScheme: kubeadm.AddToScheme,
|
||||
},
|
||||
announced.VersionToSchemeFunc{
|
||||
v1alpha1.SchemeGroupVersion.Version: v1alpha1.AddToScheme,
|
||||
},
|
||||
).Announce(groupFactoryRegistry).RegisterAndEnable(registry, scheme); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
28
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/install/install_test.go
generated
vendored
Normal file
28
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/install/install_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
Copyright 2017 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 install
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/testing/roundtrip"
|
||||
kubeadmfuzzer "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/fuzzer"
|
||||
)
|
||||
|
||||
func TestRoundTripTypes(t *testing.T) {
|
||||
roundtrip.RoundTripTestForAPIGroup(t, Install, kubeadmfuzzer.Funcs)
|
||||
}
|
||||
51
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/register.go
generated
vendored
Normal file
51
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/register.go
generated
vendored
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
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 kubeadm
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
// GroupName is the group name use in this package
|
||||
const GroupName = "kubeadm.k8s.io"
|
||||
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal}
|
||||
|
||||
var (
|
||||
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
// Kind takes an unqualified kind and returns a Group qualified GroupKind
|
||||
func Kind(kind string) schema.GroupKind {
|
||||
return SchemeGroupVersion.WithKind(kind).GroupKind()
|
||||
}
|
||||
|
||||
// Resource takes an unqualified resource and returns a Group qualified GroupResource
|
||||
func Resource(resource string) schema.GroupResource {
|
||||
return SchemeGroupVersion.WithResource(resource).GroupResource()
|
||||
}
|
||||
|
||||
func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&MasterConfiguration{},
|
||||
&NodeConfiguration{},
|
||||
)
|
||||
return nil
|
||||
}
|
||||
132
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/types.go
generated
vendored
Normal file
132
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/types.go
generated
vendored
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
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 kubeadm
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
type MasterConfiguration struct {
|
||||
metav1.TypeMeta
|
||||
|
||||
API API
|
||||
Etcd Etcd
|
||||
Networking Networking
|
||||
KubernetesVersion string
|
||||
CloudProvider string
|
||||
NodeName string
|
||||
AuthorizationModes []string
|
||||
|
||||
Token string
|
||||
TokenTTL metav1.Duration
|
||||
|
||||
APIServerExtraArgs map[string]string
|
||||
ControllerManagerExtraArgs map[string]string
|
||||
SchedulerExtraArgs map[string]string
|
||||
|
||||
// APIServerCertSANs sets extra Subject Alternative Names for the API Server signing cert
|
||||
APIServerCertSANs []string
|
||||
// CertificatesDir specifies where to store or look for all required certificates
|
||||
CertificatesDir string
|
||||
|
||||
// ImageRepository what container registry to pull control plane images from
|
||||
ImageRepository string
|
||||
|
||||
// Container registry for core images generated by CI
|
||||
// +k8s:conversion-gen=false
|
||||
CIImageRepository string
|
||||
|
||||
// UnifiedControlPlaneImage specifies if a specific container image should be used for all control plane components
|
||||
UnifiedControlPlaneImage string
|
||||
|
||||
// FeatureGates enabled by the user
|
||||
FeatureGates map[string]bool
|
||||
}
|
||||
|
||||
type API struct {
|
||||
// AdvertiseAddress sets the address for the API server to advertise.
|
||||
AdvertiseAddress string
|
||||
// BindPort sets the secure port for the API Server to bind to
|
||||
BindPort int32
|
||||
}
|
||||
|
||||
type TokenDiscovery struct {
|
||||
ID string
|
||||
Secret string
|
||||
Addresses []string
|
||||
}
|
||||
|
||||
type Networking struct {
|
||||
ServiceSubnet string
|
||||
PodSubnet string
|
||||
DNSDomain string
|
||||
}
|
||||
|
||||
type Etcd struct {
|
||||
Endpoints []string
|
||||
CAFile string
|
||||
CertFile string
|
||||
KeyFile string
|
||||
DataDir string
|
||||
ExtraArgs map[string]string
|
||||
// Image specifies which container image to use for running etcd. If empty, automatically populated by kubeadm using the image repository and default etcd version
|
||||
Image string
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
type NodeConfiguration struct {
|
||||
metav1.TypeMeta
|
||||
|
||||
CACertPath string
|
||||
DiscoveryFile string
|
||||
DiscoveryToken string
|
||||
// Currently we only pay attention to one api server but hope to support >1 in the future
|
||||
DiscoveryTokenAPIServers []string
|
||||
NodeName string
|
||||
TLSBootstrapToken string
|
||||
Token string
|
||||
|
||||
// DiscoveryTokenCACertHashes specifies a set of public key pins to verify
|
||||
// when token-based discovery is used. The root CA found during discovery
|
||||
// must match one of these values. Specifying an empty set disables root CA
|
||||
// pinning, which can be unsafe. Each hash is specified as "<type>:<value>",
|
||||
// where the only currently supported type is "sha256". This is a hex-encoded
|
||||
// SHA-256 hash of the Subject Public Key Info (SPKI) object in DER-encoded
|
||||
// ASN.1. These hashes can be calculated using, for example, OpenSSL:
|
||||
// openssl x509 -pubkey -in ca.crt openssl rsa -pubin -outform der 2>&/dev/null | openssl dgst -sha256 -hex
|
||||
DiscoveryTokenCACertHashes []string
|
||||
|
||||
// DiscoveryTokenUnsafeSkipCAVerification allows token-based discovery
|
||||
// without CA verification via DiscoveryTokenCACertHashes. This can weaken
|
||||
// the security of kubeadm since other nodes can impersonate the master.
|
||||
DiscoveryTokenUnsafeSkipCAVerification bool
|
||||
}
|
||||
|
||||
// GetControlPlaneImageRepository returns name of image repository
|
||||
// for control plane images (API,Controller Manager,Scheduler and Proxy)
|
||||
// It will override location with CI registry name in case user requests special
|
||||
// Kubernetes version from CI build area.
|
||||
// (See: kubeadmconstants.DefaultCIImageRepository)
|
||||
func (cfg *MasterConfiguration) GetControlPlaneImageRepository() string {
|
||||
if cfg.CIImageRepository != "" {
|
||||
return cfg.CIImageRepository
|
||||
}
|
||||
return cfg.ImageRepository
|
||||
}
|
||||
40
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1/BUILD
generated
vendored
Normal file
40
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"defaults.go",
|
||||
"doc.go",
|
||||
"register.go",
|
||||
"types.go",
|
||||
"zz_generated.conversion.go",
|
||||
"zz_generated.deepcopy.go",
|
||||
"zz_generated.defaults.go",
|
||||
],
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||
"//cmd/kubeadm/app/constants:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/conversion:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
101
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1/defaults.go
generated
vendored
Normal file
101
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1/defaults.go
generated
vendored
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
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 v1alpha1
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
)
|
||||
|
||||
const (
|
||||
DefaultServiceDNSDomain = "cluster.local"
|
||||
DefaultServicesSubnet = "10.96.0.0/12"
|
||||
DefaultKubernetesVersion = "stable-1.8"
|
||||
DefaultAPIBindPort = 6443
|
||||
DefaultAuthorizationModes = "Node,RBAC"
|
||||
DefaultCACertPath = "/etc/kubernetes/pki/ca.crt"
|
||||
DefaultCertificatesDir = "/etc/kubernetes/pki"
|
||||
DefaultEtcdDataDir = "/var/lib/etcd"
|
||||
DefaultImageRepository = "gcr.io/google_containers"
|
||||
)
|
||||
|
||||
func addDefaultingFuncs(scheme *runtime.Scheme) error {
|
||||
return RegisterDefaults(scheme)
|
||||
}
|
||||
|
||||
func SetDefaults_MasterConfiguration(obj *MasterConfiguration) {
|
||||
if obj.KubernetesVersion == "" {
|
||||
obj.KubernetesVersion = DefaultKubernetesVersion
|
||||
}
|
||||
|
||||
if obj.API.BindPort == 0 {
|
||||
obj.API.BindPort = DefaultAPIBindPort
|
||||
}
|
||||
|
||||
if obj.Networking.ServiceSubnet == "" {
|
||||
obj.Networking.ServiceSubnet = DefaultServicesSubnet
|
||||
}
|
||||
|
||||
if obj.Networking.DNSDomain == "" {
|
||||
obj.Networking.DNSDomain = DefaultServiceDNSDomain
|
||||
}
|
||||
|
||||
if len(obj.AuthorizationModes) == 0 {
|
||||
obj.AuthorizationModes = strings.Split(DefaultAuthorizationModes, ",")
|
||||
}
|
||||
|
||||
if obj.CertificatesDir == "" {
|
||||
obj.CertificatesDir = DefaultCertificatesDir
|
||||
}
|
||||
|
||||
if obj.TokenTTL.Duration == 0 {
|
||||
obj.TokenTTL = metav1.Duration{
|
||||
Duration: constants.DefaultTokenDuration,
|
||||
}
|
||||
}
|
||||
|
||||
if obj.ImageRepository == "" {
|
||||
obj.ImageRepository = DefaultImageRepository
|
||||
}
|
||||
|
||||
if obj.Etcd.DataDir == "" {
|
||||
obj.Etcd.DataDir = DefaultEtcdDataDir
|
||||
}
|
||||
}
|
||||
|
||||
func SetDefaults_NodeConfiguration(obj *NodeConfiguration) {
|
||||
if obj.CACertPath == "" {
|
||||
obj.CACertPath = DefaultCACertPath
|
||||
}
|
||||
if len(obj.TLSBootstrapToken) == 0 {
|
||||
obj.TLSBootstrapToken = obj.Token
|
||||
}
|
||||
if len(obj.DiscoveryToken) == 0 && len(obj.DiscoveryFile) == 0 {
|
||||
obj.DiscoveryToken = obj.Token
|
||||
}
|
||||
// Make sure file URLs become paths
|
||||
if len(obj.DiscoveryFile) != 0 {
|
||||
u, err := url.Parse(obj.DiscoveryFile)
|
||||
if err == nil && u.Scheme == "file" {
|
||||
obj.DiscoveryFile = u.Path
|
||||
}
|
||||
}
|
||||
}
|
||||
21
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1/doc.go
generated
vendored
Normal file
21
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
// +k8s:defaulter-gen=TypeMeta
|
||||
// +groupName=kubeadm.k8s.io
|
||||
// +k8s:deepcopy-gen=package
|
||||
// +k8s:conversion-gen=k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm
|
||||
package v1alpha1 // import "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1"
|
||||
63
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1/register.go
generated
vendored
Normal file
63
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1/register.go
generated
vendored
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
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 v1alpha1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
// GroupName is the group name use in this package
|
||||
const GroupName = "kubeadm.k8s.io"
|
||||
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"}
|
||||
|
||||
var (
|
||||
// TODO: move SchemeBuilder with zz_generated.deepcopy.go to k8s.io/api.
|
||||
// localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes.
|
||||
SchemeBuilder runtime.SchemeBuilder
|
||||
localSchemeBuilder = &SchemeBuilder
|
||||
AddToScheme = localSchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
func init() {
|
||||
// We only register manually written functions here. The registration of the
|
||||
// generated functions takes place in the generated files. The separation
|
||||
// makes the code compile even when the generated files are missing.
|
||||
localSchemeBuilder.Register(addKnownTypes, addDefaultingFuncs)
|
||||
}
|
||||
|
||||
// Kind takes an unqualified kind and returns a Group qualified GroupKind
|
||||
func Kind(kind string) schema.GroupKind {
|
||||
return SchemeGroupVersion.WithKind(kind).GroupKind()
|
||||
}
|
||||
|
||||
// Resource takes an unqualified resource and returns a Group qualified GroupResource
|
||||
func Resource(resource string) schema.GroupResource {
|
||||
return SchemeGroupVersion.WithResource(resource).GroupResource()
|
||||
}
|
||||
|
||||
func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&MasterConfiguration{},
|
||||
&NodeConfiguration{},
|
||||
)
|
||||
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
|
||||
return nil
|
||||
}
|
||||
114
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1/types.go
generated
vendored
Normal file
114
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1/types.go
generated
vendored
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
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 v1alpha1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
type MasterConfiguration struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
|
||||
API API `json:"api"`
|
||||
Etcd Etcd `json:"etcd"`
|
||||
Networking Networking `json:"networking"`
|
||||
KubernetesVersion string `json:"kubernetesVersion"`
|
||||
CloudProvider string `json:"cloudProvider"`
|
||||
NodeName string `json:"nodeName"`
|
||||
AuthorizationModes []string `json:"authorizationModes,omitempty"`
|
||||
|
||||
Token string `json:"token"`
|
||||
TokenTTL metav1.Duration `json:"tokenTTL"`
|
||||
|
||||
APIServerExtraArgs map[string]string `json:"apiServerExtraArgs,omitempty"`
|
||||
ControllerManagerExtraArgs map[string]string `json:"controllerManagerExtraArgs,omitempty"`
|
||||
SchedulerExtraArgs map[string]string `json:"schedulerExtraArgs,omitempty"`
|
||||
|
||||
// APIServerCertSANs sets extra Subject Alternative Names for the API Server signing cert
|
||||
APIServerCertSANs []string `json:"apiServerCertSANs,omitempty"`
|
||||
// CertificatesDir specifies where to store or look for all required certificates
|
||||
CertificatesDir string `json:"certificatesDir"`
|
||||
|
||||
// ImageRepository what container registry to pull control plane images from
|
||||
ImageRepository string `json:"imageRepository"`
|
||||
// UnifiedControlPlaneImage specifies if a specific container image should be used for all control plane components
|
||||
UnifiedControlPlaneImage string `json:"unifiedControlPlaneImage"`
|
||||
|
||||
// FeatureGates enabled by the user
|
||||
FeatureGates map[string]bool `json:"featureGates,omitempty"`
|
||||
}
|
||||
|
||||
type API struct {
|
||||
// AdvertiseAddress sets the address for the API server to advertise.
|
||||
AdvertiseAddress string `json:"advertiseAddress"`
|
||||
// BindPort sets the secure port for the API Server to bind to
|
||||
BindPort int32 `json:"bindPort"`
|
||||
}
|
||||
|
||||
type TokenDiscovery struct {
|
||||
ID string `json:"id"`
|
||||
Secret string `json:"secret"`
|
||||
Addresses []string `json:"addresses"`
|
||||
}
|
||||
|
||||
type Networking struct {
|
||||
ServiceSubnet string `json:"serviceSubnet"`
|
||||
PodSubnet string `json:"podSubnet"`
|
||||
DNSDomain string `json:"dnsDomain"`
|
||||
}
|
||||
|
||||
type Etcd struct {
|
||||
Endpoints []string `json:"endpoints"`
|
||||
CAFile string `json:"caFile"`
|
||||
CertFile string `json:"certFile"`
|
||||
KeyFile string `json:"keyFile"`
|
||||
DataDir string `json:"dataDir"`
|
||||
ExtraArgs map[string]string `json:"extraArgs,omitempty"`
|
||||
// Image specifies which container image to use for running etcd. If empty, automatically populated by kubeadm using the image repository and default etcd version
|
||||
Image string `json:"image"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
type NodeConfiguration struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
|
||||
CACertPath string `json:"caCertPath"`
|
||||
DiscoveryFile string `json:"discoveryFile"`
|
||||
DiscoveryToken string `json:"discoveryToken"`
|
||||
DiscoveryTokenAPIServers []string `json:"discoveryTokenAPIServers,omitempty"`
|
||||
NodeName string `json:"nodeName"`
|
||||
TLSBootstrapToken string `json:"tlsBootstrapToken"`
|
||||
Token string `json:"token"`
|
||||
|
||||
// DiscoveryTokenCACertHashes specifies a set of public key pins to verify
|
||||
// when token-based discovery is used. The root CA found during discovery
|
||||
// must match one of these values. Specifying an empty set disables root CA
|
||||
// pinning, which can be unsafe. Each hash is specified as "<type>:<value>",
|
||||
// where the only currently supported type is "sha256". This is a hex-encoded
|
||||
// SHA-256 hash of the Subject Public Key Info (SPKI) object in DER-encoded
|
||||
// ASN.1. These hashes can be calculated using, for example, OpenSSL:
|
||||
// openssl x509 -pubkey -in ca.crt openssl rsa -pubin -outform der 2>&/dev/null | openssl dgst -sha256 -hex
|
||||
DiscoveryTokenCACertHashes []string `json:"discoveryTokenCACertHashes,omitempty"`
|
||||
|
||||
// DiscoveryTokenUnsafeSkipCAVerification allows token-based discovery
|
||||
// without CA verification via DiscoveryTokenCACertHashes. This can weaken
|
||||
// the security of kubeadm since other nodes can impersonate the master.
|
||||
DiscoveryTokenUnsafeSkipCAVerification bool `json:"discoveryTokenUnsafeSkipCAVerification"`
|
||||
}
|
||||
254
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1/zz_generated.conversion.go
generated
vendored
Normal file
254
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1/zz_generated.conversion.go
generated
vendored
Normal file
|
|
@ -0,0 +1,254 @@
|
|||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright 2017 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.
|
||||
*/
|
||||
|
||||
// This file was autogenerated by conversion-gen. Do not edit it manually!
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
conversion "k8s.io/apimachinery/pkg/conversion"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
kubeadm "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
func init() {
|
||||
localSchemeBuilder.Register(RegisterConversions)
|
||||
}
|
||||
|
||||
// RegisterConversions adds conversion functions to the given scheme.
|
||||
// Public to allow building arbitrary schemes.
|
||||
func RegisterConversions(scheme *runtime.Scheme) error {
|
||||
return scheme.AddGeneratedConversionFuncs(
|
||||
Convert_v1alpha1_API_To_kubeadm_API,
|
||||
Convert_kubeadm_API_To_v1alpha1_API,
|
||||
Convert_v1alpha1_Etcd_To_kubeadm_Etcd,
|
||||
Convert_kubeadm_Etcd_To_v1alpha1_Etcd,
|
||||
Convert_v1alpha1_MasterConfiguration_To_kubeadm_MasterConfiguration,
|
||||
Convert_kubeadm_MasterConfiguration_To_v1alpha1_MasterConfiguration,
|
||||
Convert_v1alpha1_Networking_To_kubeadm_Networking,
|
||||
Convert_kubeadm_Networking_To_v1alpha1_Networking,
|
||||
Convert_v1alpha1_NodeConfiguration_To_kubeadm_NodeConfiguration,
|
||||
Convert_kubeadm_NodeConfiguration_To_v1alpha1_NodeConfiguration,
|
||||
Convert_v1alpha1_TokenDiscovery_To_kubeadm_TokenDiscovery,
|
||||
Convert_kubeadm_TokenDiscovery_To_v1alpha1_TokenDiscovery,
|
||||
)
|
||||
}
|
||||
|
||||
func autoConvert_v1alpha1_API_To_kubeadm_API(in *API, out *kubeadm.API, s conversion.Scope) error {
|
||||
out.AdvertiseAddress = in.AdvertiseAddress
|
||||
out.BindPort = in.BindPort
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1alpha1_API_To_kubeadm_API is an autogenerated conversion function.
|
||||
func Convert_v1alpha1_API_To_kubeadm_API(in *API, out *kubeadm.API, s conversion.Scope) error {
|
||||
return autoConvert_v1alpha1_API_To_kubeadm_API(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_kubeadm_API_To_v1alpha1_API(in *kubeadm.API, out *API, s conversion.Scope) error {
|
||||
out.AdvertiseAddress = in.AdvertiseAddress
|
||||
out.BindPort = in.BindPort
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_kubeadm_API_To_v1alpha1_API is an autogenerated conversion function.
|
||||
func Convert_kubeadm_API_To_v1alpha1_API(in *kubeadm.API, out *API, s conversion.Scope) error {
|
||||
return autoConvert_kubeadm_API_To_v1alpha1_API(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1alpha1_Etcd_To_kubeadm_Etcd(in *Etcd, out *kubeadm.Etcd, s conversion.Scope) error {
|
||||
out.Endpoints = *(*[]string)(unsafe.Pointer(&in.Endpoints))
|
||||
out.CAFile = in.CAFile
|
||||
out.CertFile = in.CertFile
|
||||
out.KeyFile = in.KeyFile
|
||||
out.DataDir = in.DataDir
|
||||
out.ExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ExtraArgs))
|
||||
out.Image = in.Image
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1alpha1_Etcd_To_kubeadm_Etcd is an autogenerated conversion function.
|
||||
func Convert_v1alpha1_Etcd_To_kubeadm_Etcd(in *Etcd, out *kubeadm.Etcd, s conversion.Scope) error {
|
||||
return autoConvert_v1alpha1_Etcd_To_kubeadm_Etcd(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_kubeadm_Etcd_To_v1alpha1_Etcd(in *kubeadm.Etcd, out *Etcd, s conversion.Scope) error {
|
||||
out.Endpoints = *(*[]string)(unsafe.Pointer(&in.Endpoints))
|
||||
out.CAFile = in.CAFile
|
||||
out.CertFile = in.CertFile
|
||||
out.KeyFile = in.KeyFile
|
||||
out.DataDir = in.DataDir
|
||||
out.ExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ExtraArgs))
|
||||
out.Image = in.Image
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_kubeadm_Etcd_To_v1alpha1_Etcd is an autogenerated conversion function.
|
||||
func Convert_kubeadm_Etcd_To_v1alpha1_Etcd(in *kubeadm.Etcd, out *Etcd, s conversion.Scope) error {
|
||||
return autoConvert_kubeadm_Etcd_To_v1alpha1_Etcd(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1alpha1_MasterConfiguration_To_kubeadm_MasterConfiguration(in *MasterConfiguration, out *kubeadm.MasterConfiguration, s conversion.Scope) error {
|
||||
if err := Convert_v1alpha1_API_To_kubeadm_API(&in.API, &out.API, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := Convert_v1alpha1_Etcd_To_kubeadm_Etcd(&in.Etcd, &out.Etcd, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := Convert_v1alpha1_Networking_To_kubeadm_Networking(&in.Networking, &out.Networking, s); err != nil {
|
||||
return err
|
||||
}
|
||||
out.KubernetesVersion = in.KubernetesVersion
|
||||
out.CloudProvider = in.CloudProvider
|
||||
out.NodeName = in.NodeName
|
||||
out.AuthorizationModes = *(*[]string)(unsafe.Pointer(&in.AuthorizationModes))
|
||||
out.Token = in.Token
|
||||
out.TokenTTL = in.TokenTTL
|
||||
out.APIServerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.APIServerExtraArgs))
|
||||
out.ControllerManagerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ControllerManagerExtraArgs))
|
||||
out.SchedulerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.SchedulerExtraArgs))
|
||||
out.APIServerCertSANs = *(*[]string)(unsafe.Pointer(&in.APIServerCertSANs))
|
||||
out.CertificatesDir = in.CertificatesDir
|
||||
out.ImageRepository = in.ImageRepository
|
||||
out.UnifiedControlPlaneImage = in.UnifiedControlPlaneImage
|
||||
out.FeatureGates = *(*map[string]bool)(unsafe.Pointer(&in.FeatureGates))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1alpha1_MasterConfiguration_To_kubeadm_MasterConfiguration is an autogenerated conversion function.
|
||||
func Convert_v1alpha1_MasterConfiguration_To_kubeadm_MasterConfiguration(in *MasterConfiguration, out *kubeadm.MasterConfiguration, s conversion.Scope) error {
|
||||
return autoConvert_v1alpha1_MasterConfiguration_To_kubeadm_MasterConfiguration(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_kubeadm_MasterConfiguration_To_v1alpha1_MasterConfiguration(in *kubeadm.MasterConfiguration, out *MasterConfiguration, s conversion.Scope) error {
|
||||
if err := Convert_kubeadm_API_To_v1alpha1_API(&in.API, &out.API, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := Convert_kubeadm_Etcd_To_v1alpha1_Etcd(&in.Etcd, &out.Etcd, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := Convert_kubeadm_Networking_To_v1alpha1_Networking(&in.Networking, &out.Networking, s); err != nil {
|
||||
return err
|
||||
}
|
||||
out.KubernetesVersion = in.KubernetesVersion
|
||||
out.CloudProvider = in.CloudProvider
|
||||
out.NodeName = in.NodeName
|
||||
out.AuthorizationModes = *(*[]string)(unsafe.Pointer(&in.AuthorizationModes))
|
||||
out.Token = in.Token
|
||||
out.TokenTTL = in.TokenTTL
|
||||
out.APIServerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.APIServerExtraArgs))
|
||||
out.ControllerManagerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ControllerManagerExtraArgs))
|
||||
out.SchedulerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.SchedulerExtraArgs))
|
||||
out.APIServerCertSANs = *(*[]string)(unsafe.Pointer(&in.APIServerCertSANs))
|
||||
out.CertificatesDir = in.CertificatesDir
|
||||
out.ImageRepository = in.ImageRepository
|
||||
// INFO: in.CIImageRepository opted out of conversion generation
|
||||
out.UnifiedControlPlaneImage = in.UnifiedControlPlaneImage
|
||||
out.FeatureGates = *(*map[string]bool)(unsafe.Pointer(&in.FeatureGates))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_kubeadm_MasterConfiguration_To_v1alpha1_MasterConfiguration is an autogenerated conversion function.
|
||||
func Convert_kubeadm_MasterConfiguration_To_v1alpha1_MasterConfiguration(in *kubeadm.MasterConfiguration, out *MasterConfiguration, s conversion.Scope) error {
|
||||
return autoConvert_kubeadm_MasterConfiguration_To_v1alpha1_MasterConfiguration(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1alpha1_Networking_To_kubeadm_Networking(in *Networking, out *kubeadm.Networking, s conversion.Scope) error {
|
||||
out.ServiceSubnet = in.ServiceSubnet
|
||||
out.PodSubnet = in.PodSubnet
|
||||
out.DNSDomain = in.DNSDomain
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1alpha1_Networking_To_kubeadm_Networking is an autogenerated conversion function.
|
||||
func Convert_v1alpha1_Networking_To_kubeadm_Networking(in *Networking, out *kubeadm.Networking, s conversion.Scope) error {
|
||||
return autoConvert_v1alpha1_Networking_To_kubeadm_Networking(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_kubeadm_Networking_To_v1alpha1_Networking(in *kubeadm.Networking, out *Networking, s conversion.Scope) error {
|
||||
out.ServiceSubnet = in.ServiceSubnet
|
||||
out.PodSubnet = in.PodSubnet
|
||||
out.DNSDomain = in.DNSDomain
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_kubeadm_Networking_To_v1alpha1_Networking is an autogenerated conversion function.
|
||||
func Convert_kubeadm_Networking_To_v1alpha1_Networking(in *kubeadm.Networking, out *Networking, s conversion.Scope) error {
|
||||
return autoConvert_kubeadm_Networking_To_v1alpha1_Networking(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1alpha1_NodeConfiguration_To_kubeadm_NodeConfiguration(in *NodeConfiguration, out *kubeadm.NodeConfiguration, s conversion.Scope) error {
|
||||
out.CACertPath = in.CACertPath
|
||||
out.DiscoveryFile = in.DiscoveryFile
|
||||
out.DiscoveryToken = in.DiscoveryToken
|
||||
out.DiscoveryTokenAPIServers = *(*[]string)(unsafe.Pointer(&in.DiscoveryTokenAPIServers))
|
||||
out.NodeName = in.NodeName
|
||||
out.TLSBootstrapToken = in.TLSBootstrapToken
|
||||
out.Token = in.Token
|
||||
out.DiscoveryTokenCACertHashes = *(*[]string)(unsafe.Pointer(&in.DiscoveryTokenCACertHashes))
|
||||
out.DiscoveryTokenUnsafeSkipCAVerification = in.DiscoveryTokenUnsafeSkipCAVerification
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1alpha1_NodeConfiguration_To_kubeadm_NodeConfiguration is an autogenerated conversion function.
|
||||
func Convert_v1alpha1_NodeConfiguration_To_kubeadm_NodeConfiguration(in *NodeConfiguration, out *kubeadm.NodeConfiguration, s conversion.Scope) error {
|
||||
return autoConvert_v1alpha1_NodeConfiguration_To_kubeadm_NodeConfiguration(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_kubeadm_NodeConfiguration_To_v1alpha1_NodeConfiguration(in *kubeadm.NodeConfiguration, out *NodeConfiguration, s conversion.Scope) error {
|
||||
out.CACertPath = in.CACertPath
|
||||
out.DiscoveryFile = in.DiscoveryFile
|
||||
out.DiscoveryToken = in.DiscoveryToken
|
||||
out.DiscoveryTokenAPIServers = *(*[]string)(unsafe.Pointer(&in.DiscoveryTokenAPIServers))
|
||||
out.NodeName = in.NodeName
|
||||
out.TLSBootstrapToken = in.TLSBootstrapToken
|
||||
out.Token = in.Token
|
||||
out.DiscoveryTokenCACertHashes = *(*[]string)(unsafe.Pointer(&in.DiscoveryTokenCACertHashes))
|
||||
out.DiscoveryTokenUnsafeSkipCAVerification = in.DiscoveryTokenUnsafeSkipCAVerification
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_kubeadm_NodeConfiguration_To_v1alpha1_NodeConfiguration is an autogenerated conversion function.
|
||||
func Convert_kubeadm_NodeConfiguration_To_v1alpha1_NodeConfiguration(in *kubeadm.NodeConfiguration, out *NodeConfiguration, s conversion.Scope) error {
|
||||
return autoConvert_kubeadm_NodeConfiguration_To_v1alpha1_NodeConfiguration(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1alpha1_TokenDiscovery_To_kubeadm_TokenDiscovery(in *TokenDiscovery, out *kubeadm.TokenDiscovery, s conversion.Scope) error {
|
||||
out.ID = in.ID
|
||||
out.Secret = in.Secret
|
||||
out.Addresses = *(*[]string)(unsafe.Pointer(&in.Addresses))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1alpha1_TokenDiscovery_To_kubeadm_TokenDiscovery is an autogenerated conversion function.
|
||||
func Convert_v1alpha1_TokenDiscovery_To_kubeadm_TokenDiscovery(in *TokenDiscovery, out *kubeadm.TokenDiscovery, s conversion.Scope) error {
|
||||
return autoConvert_v1alpha1_TokenDiscovery_To_kubeadm_TokenDiscovery(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_kubeadm_TokenDiscovery_To_v1alpha1_TokenDiscovery(in *kubeadm.TokenDiscovery, out *TokenDiscovery, s conversion.Scope) error {
|
||||
out.ID = in.ID
|
||||
out.Secret = in.Secret
|
||||
out.Addresses = *(*[]string)(unsafe.Pointer(&in.Addresses))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_kubeadm_TokenDiscovery_To_v1alpha1_TokenDiscovery is an autogenerated conversion function.
|
||||
func Convert_kubeadm_TokenDiscovery_To_v1alpha1_TokenDiscovery(in *kubeadm.TokenDiscovery, out *TokenDiscovery, s conversion.Scope) error {
|
||||
return autoConvert_kubeadm_TokenDiscovery_To_v1alpha1_TokenDiscovery(in, out, s)
|
||||
}
|
||||
244
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1/zz_generated.deepcopy.go
generated
vendored
Normal file
244
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1/zz_generated.deepcopy.go
generated
vendored
Normal file
|
|
@ -0,0 +1,244 @@
|
|||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright 2017 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.
|
||||
*/
|
||||
|
||||
// This file was autogenerated by deepcopy-gen. Do not edit it manually!
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
conversion "k8s.io/apimachinery/pkg/conversion"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
||||
// GetGeneratedDeepCopyFuncs returns the generated funcs, since we aren't registering them.
|
||||
//
|
||||
// Deprecated: deepcopy registration will go away when static deepcopy is fully implemented.
|
||||
func GetGeneratedDeepCopyFuncs() []conversion.GeneratedDeepCopyFunc {
|
||||
return []conversion.GeneratedDeepCopyFunc{
|
||||
{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
in.(*API).DeepCopyInto(out.(*API))
|
||||
return nil
|
||||
}, InType: reflect.TypeOf(&API{})},
|
||||
{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
in.(*Etcd).DeepCopyInto(out.(*Etcd))
|
||||
return nil
|
||||
}, InType: reflect.TypeOf(&Etcd{})},
|
||||
{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
in.(*MasterConfiguration).DeepCopyInto(out.(*MasterConfiguration))
|
||||
return nil
|
||||
}, InType: reflect.TypeOf(&MasterConfiguration{})},
|
||||
{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
in.(*Networking).DeepCopyInto(out.(*Networking))
|
||||
return nil
|
||||
}, InType: reflect.TypeOf(&Networking{})},
|
||||
{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
in.(*NodeConfiguration).DeepCopyInto(out.(*NodeConfiguration))
|
||||
return nil
|
||||
}, InType: reflect.TypeOf(&NodeConfiguration{})},
|
||||
{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
in.(*TokenDiscovery).DeepCopyInto(out.(*TokenDiscovery))
|
||||
return nil
|
||||
}, InType: reflect.TypeOf(&TokenDiscovery{})},
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *API) DeepCopyInto(out *API) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new API.
|
||||
func (in *API) DeepCopy() *API {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(API)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Etcd) DeepCopyInto(out *Etcd) {
|
||||
*out = *in
|
||||
if in.Endpoints != nil {
|
||||
in, out := &in.Endpoints, &out.Endpoints
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.ExtraArgs != nil {
|
||||
in, out := &in.ExtraArgs, &out.ExtraArgs
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Etcd.
|
||||
func (in *Etcd) DeepCopy() *Etcd {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Etcd)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *MasterConfiguration) DeepCopyInto(out *MasterConfiguration) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
out.API = in.API
|
||||
in.Etcd.DeepCopyInto(&out.Etcd)
|
||||
out.Networking = in.Networking
|
||||
if in.AuthorizationModes != nil {
|
||||
in, out := &in.AuthorizationModes, &out.AuthorizationModes
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
out.TokenTTL = in.TokenTTL
|
||||
if in.APIServerExtraArgs != nil {
|
||||
in, out := &in.APIServerExtraArgs, &out.APIServerExtraArgs
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.ControllerManagerExtraArgs != nil {
|
||||
in, out := &in.ControllerManagerExtraArgs, &out.ControllerManagerExtraArgs
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.SchedulerExtraArgs != nil {
|
||||
in, out := &in.SchedulerExtraArgs, &out.SchedulerExtraArgs
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.APIServerCertSANs != nil {
|
||||
in, out := &in.APIServerCertSANs, &out.APIServerCertSANs
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.FeatureGates != nil {
|
||||
in, out := &in.FeatureGates, &out.FeatureGates
|
||||
*out = make(map[string]bool, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MasterConfiguration.
|
||||
func (in *MasterConfiguration) DeepCopy() *MasterConfiguration {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(MasterConfiguration)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *MasterConfiguration) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Networking) DeepCopyInto(out *Networking) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Networking.
|
||||
func (in *Networking) DeepCopy() *Networking {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Networking)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *NodeConfiguration) DeepCopyInto(out *NodeConfiguration) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
if in.DiscoveryTokenAPIServers != nil {
|
||||
in, out := &in.DiscoveryTokenAPIServers, &out.DiscoveryTokenAPIServers
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.DiscoveryTokenCACertHashes != nil {
|
||||
in, out := &in.DiscoveryTokenCACertHashes, &out.DiscoveryTokenCACertHashes
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeConfiguration.
|
||||
func (in *NodeConfiguration) DeepCopy() *NodeConfiguration {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(NodeConfiguration)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *NodeConfiguration) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *TokenDiscovery) DeepCopyInto(out *TokenDiscovery) {
|
||||
*out = *in
|
||||
if in.Addresses != nil {
|
||||
in, out := &in.Addresses, &out.Addresses
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TokenDiscovery.
|
||||
func (in *TokenDiscovery) DeepCopy() *TokenDiscovery {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(TokenDiscovery)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
42
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1/zz_generated.defaults.go
generated
vendored
Normal file
42
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1/zz_generated.defaults.go
generated
vendored
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright 2017 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.
|
||||
*/
|
||||
|
||||
// This file was autogenerated by defaulter-gen. Do not edit it manually!
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// RegisterDefaults adds defaulters functions to the given scheme.
|
||||
// Public to allow building arbitrary schemes.
|
||||
// All generated defaulters are covering - they call all nested defaulters.
|
||||
func RegisterDefaults(scheme *runtime.Scheme) error {
|
||||
scheme.AddTypeDefaultingFunc(&MasterConfiguration{}, func(obj interface{}) { SetObjectDefaults_MasterConfiguration(obj.(*MasterConfiguration)) })
|
||||
scheme.AddTypeDefaultingFunc(&NodeConfiguration{}, func(obj interface{}) { SetObjectDefaults_NodeConfiguration(obj.(*NodeConfiguration)) })
|
||||
return nil
|
||||
}
|
||||
|
||||
func SetObjectDefaults_MasterConfiguration(in *MasterConfiguration) {
|
||||
SetDefaults_MasterConfiguration(in)
|
||||
}
|
||||
|
||||
func SetObjectDefaults_NodeConfiguration(in *NodeConfiguration) {
|
||||
SetDefaults_NodeConfiguration(in)
|
||||
}
|
||||
50
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation/BUILD
generated
vendored
Normal file
50
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["validation_test.go"],
|
||||
library = ":go_default_library",
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["validation.go"],
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||
"//cmd/kubeadm/app/constants:go_default_library",
|
||||
"//cmd/kubeadm/app/features:go_default_library",
|
||||
"//cmd/kubeadm/app/util:go_default_library",
|
||||
"//cmd/kubeadm/app/util/token:go_default_library",
|
||||
"//pkg/api/validation:go_default_library",
|
||||
"//pkg/kubeapiserver/authorizer/modes:go_default_library",
|
||||
"//pkg/registry/core/service/ipallocator:go_default_library",
|
||||
"//pkg/util/node:go_default_library",
|
||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/validation:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
323
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation/validation.go
generated
vendored
Normal file
323
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation/validation.go
generated
vendored
Normal file
|
|
@ -0,0 +1,323 @@
|
|||
/*
|
||||
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 validation
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/validation"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/features"
|
||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||
tokenutil "k8s.io/kubernetes/cmd/kubeadm/app/util/token"
|
||||
apivalidation "k8s.io/kubernetes/pkg/api/validation"
|
||||
authzmodes "k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes"
|
||||
"k8s.io/kubernetes/pkg/registry/core/service/ipallocator"
|
||||
"k8s.io/kubernetes/pkg/util/node"
|
||||
)
|
||||
|
||||
// TODO: Break out the cloudprovider functionality out of core and only support the new flow
|
||||
// described in https://github.com/kubernetes/community/pull/128
|
||||
var cloudproviders = []string{
|
||||
"aws",
|
||||
"azure",
|
||||
"cloudstack",
|
||||
"gce",
|
||||
"openstack",
|
||||
"ovirt",
|
||||
"photon",
|
||||
"rackspace",
|
||||
"vsphere",
|
||||
}
|
||||
|
||||
// Describes the authorization modes that are enforced by kubeadm
|
||||
var requiredAuthzModes = []string{
|
||||
authzmodes.ModeRBAC,
|
||||
authzmodes.ModeNode,
|
||||
}
|
||||
|
||||
func ValidateMasterConfiguration(c *kubeadm.MasterConfiguration) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
allErrs = append(allErrs, ValidateCloudProvider(c.CloudProvider, field.NewPath("cloudprovider"))...)
|
||||
allErrs = append(allErrs, ValidateAuthorizationModes(c.AuthorizationModes, field.NewPath("authorization-modes"))...)
|
||||
allErrs = append(allErrs, ValidateNetworking(&c.Networking, field.NewPath("networking"))...)
|
||||
allErrs = append(allErrs, ValidateAPIServerCertSANs(c.APIServerCertSANs, field.NewPath("cert-altnames"))...)
|
||||
allErrs = append(allErrs, ValidateAbsolutePath(c.CertificatesDir, field.NewPath("certificates-dir"))...)
|
||||
allErrs = append(allErrs, ValidateNodeName(c.NodeName, field.NewPath("node-name"))...)
|
||||
allErrs = append(allErrs, ValidateToken(c.Token, field.NewPath("token"))...)
|
||||
allErrs = append(allErrs, ValidateFeatureGates(c.FeatureGates, field.NewPath("feature-gates"))...)
|
||||
allErrs = append(allErrs, ValidateAPIEndpoint(c, field.NewPath("api-endpoint"))...)
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidateNodeConfiguration(c *kubeadm.NodeConfiguration) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
allErrs = append(allErrs, ValidateDiscovery(c, field.NewPath("discovery"))...)
|
||||
|
||||
if !filepath.IsAbs(c.CACertPath) || !strings.HasSuffix(c.CACertPath, ".crt") {
|
||||
allErrs = append(allErrs, field.Invalid(field.NewPath("ca-cert-path"), c.CACertPath, "the ca certificate path must be an absolute path"))
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidateAuthorizationModes(authzModes []string, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
found := map[string]bool{}
|
||||
|
||||
for _, authzMode := range authzModes {
|
||||
if !authzmodes.IsValidAuthorizationMode(authzMode) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, authzMode, "invalid authorization mode"))
|
||||
}
|
||||
|
||||
if found[authzMode] {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, authzMode, "duplicate authorization mode"))
|
||||
continue
|
||||
}
|
||||
found[authzMode] = true
|
||||
}
|
||||
for _, requiredMode := range requiredAuthzModes {
|
||||
if !found[requiredMode] {
|
||||
allErrs = append(allErrs, field.Required(fldPath, fmt.Sprintf("authorization mode %s must be enabled", requiredMode)))
|
||||
}
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidateDiscovery(c *kubeadm.NodeConfiguration, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
if len(c.DiscoveryToken) != 0 {
|
||||
allErrs = append(allErrs, ValidateToken(c.DiscoveryToken, fldPath)...)
|
||||
}
|
||||
if len(c.DiscoveryFile) != 0 {
|
||||
allErrs = append(allErrs, ValidateDiscoveryFile(c.DiscoveryFile, fldPath)...)
|
||||
}
|
||||
allErrs = append(allErrs, ValidateArgSelection(c, fldPath)...)
|
||||
allErrs = append(allErrs, ValidateToken(c.TLSBootstrapToken, fldPath)...)
|
||||
allErrs = append(allErrs, ValidateJoinDiscoveryTokenAPIServer(c, fldPath)...)
|
||||
|
||||
if len(c.DiscoveryToken) != 0 {
|
||||
allErrs = append(allErrs, ValidateToken(c.DiscoveryToken, fldPath)...)
|
||||
}
|
||||
if len(c.DiscoveryFile) != 0 {
|
||||
allErrs = append(allErrs, ValidateDiscoveryFile(c.DiscoveryFile, fldPath)...)
|
||||
}
|
||||
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidateArgSelection(cfg *kubeadm.NodeConfiguration, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
if len(cfg.DiscoveryToken) != 0 && len(cfg.DiscoveryFile) != 0 {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, "", "DiscoveryToken and DiscoveryFile cannot both be set"))
|
||||
}
|
||||
if len(cfg.DiscoveryToken) == 0 && len(cfg.DiscoveryFile) == 0 {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, "", "DiscoveryToken or DiscoveryFile must be set"))
|
||||
}
|
||||
if len(cfg.DiscoveryTokenAPIServers) < 1 && len(cfg.DiscoveryToken) != 0 {
|
||||
allErrs = append(allErrs, field.Required(fldPath, "DiscoveryTokenAPIServers not set"))
|
||||
}
|
||||
|
||||
if len(cfg.DiscoveryFile) != 0 && len(cfg.DiscoveryTokenCACertHashes) != 0 {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, "", "DiscoveryTokenCACertHashes cannot be used with DiscoveryFile"))
|
||||
}
|
||||
|
||||
// TODO: convert this warning to an error after v1.8
|
||||
if len(cfg.DiscoveryFile) == 0 && len(cfg.DiscoveryTokenCACertHashes) == 0 && !cfg.DiscoveryTokenUnsafeSkipCAVerification {
|
||||
fmt.Println("[validation] WARNING: using token-based discovery without DiscoveryTokenCACertHashes can be unsafe (see https://kubernetes.io/docs/admin/kubeadm/#kubeadm-join).")
|
||||
fmt.Println("[validation] WARNING: Pass --discovery-token-unsafe-skip-ca-verification to disable this warning. This warning will become an error in Kubernetes 1.9.")
|
||||
}
|
||||
|
||||
// TODO remove once we support multiple api servers
|
||||
if len(cfg.DiscoveryTokenAPIServers) > 1 {
|
||||
fmt.Println("[validation] WARNING: kubeadm doesn't fully support multiple API Servers yet")
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidateJoinDiscoveryTokenAPIServer(c *kubeadm.NodeConfiguration, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
for _, m := range c.DiscoveryTokenAPIServers {
|
||||
_, _, err := net.SplitHostPort(m)
|
||||
if err != nil {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, m, err.Error()))
|
||||
}
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidateDiscoveryFile(discoveryFile string, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
u, err := url.Parse(discoveryFile)
|
||||
if err != nil {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, discoveryFile, "not a valid HTTPS URL or a file on disk"))
|
||||
return allErrs
|
||||
}
|
||||
|
||||
if u.Scheme == "" {
|
||||
// URIs with no scheme should be treated as files
|
||||
if _, err := os.Stat(discoveryFile); os.IsNotExist(err) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, discoveryFile, "not a valid HTTPS URL or a file on disk"))
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
if u.Scheme != "https" {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, discoveryFile, "if an URL is used, the scheme must be https"))
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidateToken(t string, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
id, secret, err := tokenutil.ParseToken(t)
|
||||
if err != nil {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, t, err.Error()))
|
||||
}
|
||||
|
||||
if len(id) == 0 || len(secret) == 0 {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, t, "token must be of form '[a-z0-9]{6}.[a-z0-9]{16}'"))
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidateAPIServerCertSANs(altnames []string, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
for _, altname := range altnames {
|
||||
if len(validation.IsDNS1123Subdomain(altname)) != 0 && net.ParseIP(altname) == nil {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, altname, "altname is not a valid dns label or ip address"))
|
||||
}
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidateIPFromString(ipaddr string, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
if net.ParseIP(ipaddr) == nil {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, ipaddr, "ip address is not valid"))
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidateIPNetFromString(subnet string, minAddrs int64, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
_, svcSubnet, err := net.ParseCIDR(subnet)
|
||||
if err != nil {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, subnet, "couldn't parse subnet"))
|
||||
return allErrs
|
||||
}
|
||||
numAddresses := ipallocator.RangeSize(svcSubnet)
|
||||
if numAddresses < minAddrs {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, subnet, "subnet is too small"))
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidateNetworking(c *kubeadm.Networking, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
allErrs = append(allErrs, apivalidation.ValidateDNS1123Subdomain(c.DNSDomain, field.NewPath("dns-domain"))...)
|
||||
allErrs = append(allErrs, ValidateIPNetFromString(c.ServiceSubnet, constants.MinimumAddressesInServiceSubnet, field.NewPath("service-subnet"))...)
|
||||
if len(c.PodSubnet) != 0 {
|
||||
allErrs = append(allErrs, ValidateIPNetFromString(c.PodSubnet, constants.MinimumAddressesInServiceSubnet, field.NewPath("pod-subnet"))...)
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidateAbsolutePath(path string, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
if !filepath.IsAbs(path) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, path, "path is not absolute"))
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidateNodeName(nodename string, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
if node.GetHostname(nodename) != nodename {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, nodename, "nodename is not valid, must be lower case"))
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidateCloudProvider(provider string, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
if len(provider) == 0 {
|
||||
return allErrs
|
||||
}
|
||||
for _, supported := range cloudproviders {
|
||||
if provider == supported {
|
||||
return allErrs
|
||||
}
|
||||
}
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, provider, "cloudprovider not supported"))
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidateMixedArguments(flag *pflag.FlagSet) error {
|
||||
// If --config isn't set, we have nothing to validate
|
||||
if !flag.Changed("config") {
|
||||
return nil
|
||||
}
|
||||
|
||||
mixedInvalidFlags := []string{}
|
||||
flag.Visit(func(f *pflag.Flag) {
|
||||
if f.Name == "config" || strings.HasPrefix(f.Name, "skip-") || f.Name == "dry-run" || f.Name == "kubeconfig" {
|
||||
// "--skip-*" flags or other whitelisted flags can be set with --config
|
||||
return
|
||||
}
|
||||
mixedInvalidFlags = append(mixedInvalidFlags, f.Name)
|
||||
})
|
||||
|
||||
if len(mixedInvalidFlags) != 0 {
|
||||
return fmt.Errorf("can not mix '--config' with arguments %v", mixedInvalidFlags)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func ValidateFeatureGates(featureGates map[string]bool, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
validFeatures := features.Keys(features.InitFeatureGates)
|
||||
|
||||
// check valid feature names are provided
|
||||
for k := range featureGates {
|
||||
if !features.Supports(features.InitFeatureGates, k) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, featureGates,
|
||||
fmt.Sprintf("%s is not a valid feature name. Valid features are: %s", k, validFeatures)))
|
||||
}
|
||||
}
|
||||
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidateAPIEndpoint(c *kubeadm.MasterConfiguration, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
endpoint, err := kubeadmutil.GetMasterEndpoint(c)
|
||||
if err != nil {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, endpoint, "Invalid API Endpoint"))
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
461
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation/validation_test.go
generated
vendored
Normal file
461
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation/validation_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,461 @@
|
|||
/*
|
||||
Copyright 2017 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 validation
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
)
|
||||
|
||||
func TestValidateTokenDiscovery(t *testing.T) {
|
||||
var tests = []struct {
|
||||
c *kubeadm.NodeConfiguration
|
||||
f *field.Path
|
||||
expected bool
|
||||
}{
|
||||
{&kubeadm.NodeConfiguration{Token: "772ef5.6b6baab1d4a0a171", DiscoveryTokenAPIServers: []string{"192.168.122.100:9898"}}, nil, true},
|
||||
{&kubeadm.NodeConfiguration{Token: ".6b6baab1d4a0a171", DiscoveryTokenAPIServers: []string{"192.168.122.100:9898"}}, nil, false},
|
||||
{&kubeadm.NodeConfiguration{Token: "772ef5.", DiscoveryTokenAPIServers: []string{"192.168.122.100:9898"}}, nil, false},
|
||||
{&kubeadm.NodeConfiguration{Token: "772ef5.6b6baab1d4a0a171", DiscoveryTokenAPIServers: []string{"2001:db8::100:9898"}}, nil, true},
|
||||
{&kubeadm.NodeConfiguration{Token: ".6b6baab1d4a0a171", DiscoveryTokenAPIServers: []string{"2001:db8::100:9898"}}, nil, false},
|
||||
{&kubeadm.NodeConfiguration{Token: "772ef5.", DiscoveryTokenAPIServers: []string{"2001:db8::100:9898"}}, nil, false},
|
||||
}
|
||||
for _, rt := range tests {
|
||||
err := ValidateToken(rt.c.Token, rt.f).ToAggregate()
|
||||
if (err == nil) != rt.expected {
|
||||
t.Errorf(
|
||||
"failed ValidateTokenDiscovery:\n\texpected: %t\n\t actual: %t",
|
||||
rt.expected,
|
||||
(err == nil),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateAuthorizationModes(t *testing.T) {
|
||||
var tests = []struct {
|
||||
s []string
|
||||
f *field.Path
|
||||
expected bool
|
||||
}{
|
||||
{[]string{""}, nil, false},
|
||||
{[]string{"rBAC"}, nil, false}, // mode not supported
|
||||
{[]string{"rBAC", "Webhook"}, nil, false}, // mode not supported
|
||||
{[]string{"RBAC", "Webhook"}, nil, false}, // mode Node required
|
||||
{[]string{"Node", "RBAC", "Webhook", "Webhook"}, nil, false}, // no duplicates allowed
|
||||
{[]string{"not valid"}, nil, false}, // invalid mode
|
||||
{[]string{"Node", "RBAC"}, nil, true}, // supported
|
||||
{[]string{"RBAC", "Node"}, nil, true}, // supported
|
||||
{[]string{"Node", "RBAC", "Webhook", "ABAC"}, nil, true}, // supported
|
||||
}
|
||||
for _, rt := range tests {
|
||||
actual := ValidateAuthorizationModes(rt.s, rt.f)
|
||||
if (len(actual) == 0) != rt.expected {
|
||||
t.Errorf(
|
||||
"failed ValidateAuthorizationModes:\n\texpected: %t\n\t actual: %t",
|
||||
rt.expected,
|
||||
(len(actual) == 0),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateNodeName(t *testing.T) {
|
||||
var tests = []struct {
|
||||
s string
|
||||
f *field.Path
|
||||
expected bool
|
||||
}{
|
||||
{"", nil, false}, // ok if not provided
|
||||
{"1234", nil, true}, // supported
|
||||
{"valid-nodename", nil, true}, // supported
|
||||
{"INVALID-NODENAME", nil, false}, // Upper cases is invalid
|
||||
}
|
||||
for _, rt := range tests {
|
||||
actual := ValidateNodeName(rt.s, rt.f)
|
||||
if (len(actual) == 0) != rt.expected {
|
||||
t.Errorf(
|
||||
"failed ValidateNodeName:\n\texpected: %t\n\t actual: %t",
|
||||
rt.expected,
|
||||
(len(actual) == 0),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateCloudProvider(t *testing.T) {
|
||||
var tests = []struct {
|
||||
s string
|
||||
f *field.Path
|
||||
expected bool
|
||||
}{
|
||||
{"", nil, true}, // if not provided, ok, it's optional
|
||||
{"1234", nil, false}, // not supported
|
||||
{"awws", nil, false}, // not supported
|
||||
{"aws", nil, true}, // supported
|
||||
{"gce", nil, true}, // supported
|
||||
}
|
||||
for _, rt := range tests {
|
||||
actual := ValidateCloudProvider(rt.s, rt.f)
|
||||
if (len(actual) == 0) != rt.expected {
|
||||
t.Errorf(
|
||||
"failed ValidateCloudProvider:\n\texpected: %t\n\t actual: %t",
|
||||
rt.expected,
|
||||
(len(actual) == 0),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateAPIServerCertSANs(t *testing.T) {
|
||||
var tests = []struct {
|
||||
sans []string
|
||||
expected bool
|
||||
}{
|
||||
{[]string{}, true}, // ok if not provided
|
||||
{[]string{"1,2,,3"}, false}, // not a DNS label or IP
|
||||
{[]string{"my-hostname", "???&?.garbage"}, false}, // not valid
|
||||
{[]string{"my-hostname", "my.subdomain", "1.2.3.4"}, true}, // supported
|
||||
{[]string{"my-hostname2", "my.other.subdomain", "10.0.0.10"}, true}, // supported
|
||||
{[]string{"my-hostname", "my.subdomain", "2001:db8::4"}, true}, // supported
|
||||
{[]string{"my-hostname2", "my.other.subdomain", "2001:db8::10"}, true}, // supported
|
||||
}
|
||||
for _, rt := range tests {
|
||||
actual := ValidateAPIServerCertSANs(rt.sans, nil)
|
||||
if (len(actual) == 0) != rt.expected {
|
||||
t.Errorf(
|
||||
"failed ValidateAPIServerCertSANs:\n\texpected: %t\n\t actual: %t",
|
||||
rt.expected,
|
||||
(len(actual) == 0),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateIPFromString(t *testing.T) {
|
||||
var tests = []struct {
|
||||
name string
|
||||
ip string
|
||||
expected bool
|
||||
}{
|
||||
{"invalid missing address", "", false},
|
||||
{"invalid missing decimal points in IPv4 address", "1234", false},
|
||||
{"invalid incomplete IPv4 address", "1.2", false},
|
||||
{"invalid IPv4 CIDR provided instead of IPv4 address", "1.2.3.4/16", false},
|
||||
{"valid IPv4 address", "1.2.3.4", true},
|
||||
{"valid IPv6 address", "2001:db8::1", true},
|
||||
{"invalid IPv6 CIDR provided instead of IPv6 address", "2001:db8::1/64", false},
|
||||
{"invalid hex character in IPv6 address", "2001:xb8::", false},
|
||||
{"invalid use of colons in IPv6 address", "2001::db8::", false},
|
||||
}
|
||||
for _, rt := range tests {
|
||||
actual := ValidateIPFromString(rt.ip, nil)
|
||||
if (len(actual) == 0) != rt.expected {
|
||||
t.Errorf(
|
||||
"%s test case failed:\n\texpected: %t\n\t actual: %t",
|
||||
rt.name,
|
||||
rt.expected,
|
||||
(len(actual) == 0),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateIPNetFromString(t *testing.T) {
|
||||
var tests = []struct {
|
||||
name string
|
||||
subnet string
|
||||
minaddrs int64
|
||||
expected bool
|
||||
}{
|
||||
{"invalid missing CIDR", "", 0, false},
|
||||
{"invalid CIDR missing decimal points in IPv4 address and / mask", "1234", 0, false},
|
||||
{"invalid CIDR use of letters instead of numbers and / mask", "abc", 0, false},
|
||||
{"invalid IPv4 address provided instead of CIDR representation", "1.2.3.4", 0, false},
|
||||
{"invalid IPv6 address provided instead of CIDR representation", "2001:db8::1", 0, false},
|
||||
{"valid, but IPv4 CIDR too small. At least 10 addresses needed", "10.0.0.16/29", 10, false},
|
||||
{"valid, but IPv6 CIDR too small. At least 10 addresses needed", "2001:db8::/125", 10, false},
|
||||
{"valid IPv4 CIDR", "10.0.0.16/12", 10, true},
|
||||
{"valid IPv6 CIDR", "2001:db8::/98", 10, true},
|
||||
}
|
||||
for _, rt := range tests {
|
||||
actual := ValidateIPNetFromString(rt.subnet, rt.minaddrs, nil)
|
||||
if (len(actual) == 0) != rt.expected {
|
||||
t.Errorf(
|
||||
"%s test case failed :\n\texpected: %t\n\t actual: %t",
|
||||
rt.name,
|
||||
rt.expected,
|
||||
(len(actual) == 0),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateAPIEndpoint(t *testing.T) {
|
||||
var tests = []struct {
|
||||
name string
|
||||
s *kubeadm.MasterConfiguration
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
name: "Missing configuration",
|
||||
s: &kubeadm.MasterConfiguration{},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "Valid IPv4 address and default port",
|
||||
s: &kubeadm.MasterConfiguration{
|
||||
API: kubeadm.API{
|
||||
AdvertiseAddress: "1.2.3.4",
|
||||
BindPort: 6443,
|
||||
},
|
||||
},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "Valid IPv6 address and port",
|
||||
s: &kubeadm.MasterConfiguration{
|
||||
API: kubeadm.API{
|
||||
AdvertiseAddress: "2001:db7::1",
|
||||
BindPort: 3446,
|
||||
},
|
||||
},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "Invalid IPv4 address",
|
||||
s: &kubeadm.MasterConfiguration{
|
||||
API: kubeadm.API{
|
||||
AdvertiseAddress: "1.2.34",
|
||||
BindPort: 6443,
|
||||
},
|
||||
},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "Invalid IPv6 address",
|
||||
s: &kubeadm.MasterConfiguration{
|
||||
API: kubeadm.API{
|
||||
AdvertiseAddress: "2001:db7:1",
|
||||
BindPort: 3446,
|
||||
},
|
||||
},
|
||||
expected: false,
|
||||
},
|
||||
}
|
||||
for _, rt := range tests {
|
||||
actual := ValidateAPIEndpoint(rt.s, nil)
|
||||
if (len(actual) == 0) != rt.expected {
|
||||
t.Errorf(
|
||||
"%s test case failed:\n\texpected: %t\n\t actual: %t",
|
||||
rt.name,
|
||||
rt.expected,
|
||||
(len(actual) == 0),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateMasterConfiguration(t *testing.T) {
|
||||
nodename := "valid-nodename"
|
||||
var tests = []struct {
|
||||
name string
|
||||
s *kubeadm.MasterConfiguration
|
||||
expected bool
|
||||
}{
|
||||
{"invalid missing master configuration",
|
||||
&kubeadm.MasterConfiguration{}, false},
|
||||
{"invalid missing token with IPv4 service subnet",
|
||||
&kubeadm.MasterConfiguration{
|
||||
API: kubeadm.API{
|
||||
AdvertiseAddress: "1.2.3.4",
|
||||
BindPort: 6443,
|
||||
},
|
||||
AuthorizationModes: []string{"Node", "RBAC"},
|
||||
Networking: kubeadm.Networking{
|
||||
ServiceSubnet: "10.96.0.1/12",
|
||||
DNSDomain: "cluster.local",
|
||||
},
|
||||
CertificatesDir: "/some/cert/dir",
|
||||
NodeName: nodename,
|
||||
}, false},
|
||||
{"invalid missing token with IPv6 service subnet",
|
||||
&kubeadm.MasterConfiguration{
|
||||
API: kubeadm.API{
|
||||
AdvertiseAddress: "1.2.3.4",
|
||||
BindPort: 6443,
|
||||
},
|
||||
AuthorizationModes: []string{"Node", "RBAC"},
|
||||
Networking: kubeadm.Networking{
|
||||
ServiceSubnet: "2001:db8::1/98",
|
||||
DNSDomain: "cluster.local",
|
||||
},
|
||||
CertificatesDir: "/some/cert/dir",
|
||||
NodeName: nodename,
|
||||
}, false},
|
||||
{"invalid missing node name",
|
||||
&kubeadm.MasterConfiguration{
|
||||
API: kubeadm.API{
|
||||
AdvertiseAddress: "1.2.3.4",
|
||||
BindPort: 6443,
|
||||
},
|
||||
AuthorizationModes: []string{"Node", "RBAC"},
|
||||
Networking: kubeadm.Networking{
|
||||
ServiceSubnet: "10.96.0.1/12",
|
||||
DNSDomain: "cluster.local",
|
||||
},
|
||||
CertificatesDir: "/some/other/cert/dir",
|
||||
Token: "abcdef.0123456789abcdef",
|
||||
}, false},
|
||||
{"valid master configuration with IPv4 service subnet",
|
||||
&kubeadm.MasterConfiguration{
|
||||
API: kubeadm.API{
|
||||
AdvertiseAddress: "1.2.3.4",
|
||||
BindPort: 6443,
|
||||
},
|
||||
AuthorizationModes: []string{"Node", "RBAC"},
|
||||
Networking: kubeadm.Networking{
|
||||
ServiceSubnet: "10.96.0.1/12",
|
||||
DNSDomain: "cluster.local",
|
||||
},
|
||||
CertificatesDir: "/some/other/cert/dir",
|
||||
Token: "abcdef.0123456789abcdef",
|
||||
NodeName: nodename,
|
||||
}, true},
|
||||
{"valid master configuration using IPv6 service subnet",
|
||||
&kubeadm.MasterConfiguration{
|
||||
API: kubeadm.API{
|
||||
AdvertiseAddress: "1:2:3::4",
|
||||
BindPort: 3446,
|
||||
},
|
||||
AuthorizationModes: []string{"Node", "RBAC"},
|
||||
Networking: kubeadm.Networking{
|
||||
ServiceSubnet: "2001:db8::1/98",
|
||||
DNSDomain: "cluster.local",
|
||||
},
|
||||
CertificatesDir: "/some/other/cert/dir",
|
||||
Token: "abcdef.0123456789abcdef",
|
||||
NodeName: nodename,
|
||||
}, true},
|
||||
}
|
||||
for _, rt := range tests {
|
||||
actual := ValidateMasterConfiguration(rt.s)
|
||||
if (len(actual) == 0) != rt.expected {
|
||||
t.Errorf(
|
||||
"%s test case failed:\n\texpected: %t\n\t actual: %t",
|
||||
rt.name,
|
||||
rt.expected,
|
||||
(len(actual) == 0),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateNodeConfiguration(t *testing.T) {
|
||||
var tests = []struct {
|
||||
s *kubeadm.NodeConfiguration
|
||||
expected bool
|
||||
}{
|
||||
{&kubeadm.NodeConfiguration{}, false},
|
||||
{&kubeadm.NodeConfiguration{
|
||||
DiscoveryFile: "foo",
|
||||
DiscoveryToken: "abcdef.1234567890123456@foobar",
|
||||
CACertPath: "/some/cert.crt",
|
||||
}, false},
|
||||
}
|
||||
for _, rt := range tests {
|
||||
actual := ValidateNodeConfiguration(rt.s)
|
||||
if (len(actual) == 0) != rt.expected {
|
||||
t.Errorf(
|
||||
"failed ValidateNodeConfiguration:\n\texpected: %t\n\t actual: %t",
|
||||
rt.expected,
|
||||
(len(actual) == 0),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateMixedArguments(t *testing.T) {
|
||||
var tests = []struct {
|
||||
args []string
|
||||
expected bool
|
||||
}{
|
||||
// Expected to succeed, --config is mixed with skip-* flags only or no other flags
|
||||
{[]string{"--foo=bar"}, true},
|
||||
{[]string{"--config=hello"}, true},
|
||||
{[]string{"--config=hello", "--skip-preflight-checks=true"}, true},
|
||||
{[]string{"--config=hello", "--skip-token-print=true"}, true},
|
||||
{[]string{"--config=hello", "--skip-preflight-checks", "--skip-token-print"}, true},
|
||||
// Expected to fail, --config is mixed with the --foo flag
|
||||
{[]string{"--config=hello", "--skip-preflight-checks", "--foo=bar"}, false},
|
||||
{[]string{"--config=hello", "--foo=bar"}, false},
|
||||
}
|
||||
|
||||
var cfgPath string
|
||||
|
||||
for _, rt := range tests {
|
||||
f := pflag.NewFlagSet("test", pflag.ContinueOnError)
|
||||
if f.Parsed() {
|
||||
t.Error("f.Parse() = true before Parse")
|
||||
}
|
||||
f.String("foo", "", "flag bound to config object")
|
||||
f.Bool("skip-preflight-checks", false, "flag not bound to config object")
|
||||
f.Bool("skip-token-print", false, "flag not bound to config object")
|
||||
f.StringVar(&cfgPath, "config", cfgPath, "Path to kubeadm config file")
|
||||
if err := f.Parse(rt.args); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
actual := ValidateMixedArguments(f)
|
||||
if (actual == nil) != rt.expected {
|
||||
t.Errorf(
|
||||
"failed ValidateMixedArguments:\n\texpected: %t\n\t actual: %t testdata: %v",
|
||||
rt.expected,
|
||||
(actual == nil),
|
||||
rt.args,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateFeatureGates(t *testing.T) {
|
||||
type featureFlag map[string]bool
|
||||
var tests = []struct {
|
||||
featureGates featureFlag
|
||||
expected bool
|
||||
}{
|
||||
{featureFlag{"SelfHosting": true}, true},
|
||||
{featureFlag{"SelfHosting": false}, true},
|
||||
{featureFlag{"StoreCertsInSecrets": true}, true},
|
||||
{featureFlag{"StoreCertsInSecrets": false}, true},
|
||||
{featureFlag{"Foo": true}, false},
|
||||
}
|
||||
for _, rt := range tests {
|
||||
actual := ValidateFeatureGates(rt.featureGates, nil)
|
||||
if (len(actual) == 0) != rt.expected {
|
||||
t.Errorf(
|
||||
"failed featureGates:\n\texpected: %t\n\t actual: %t",
|
||||
rt.expected,
|
||||
(len(actual) == 0),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
43
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/well_known_labels.go
generated
vendored
Normal file
43
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/well_known_labels.go
generated
vendored
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
Copyright 2017 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 kubeadm
|
||||
|
||||
// Role labels are applied to Nodes to mark their purpose. In particular, we
|
||||
// usually want to distinguish the master, so that we can isolate privileged
|
||||
// pods and operations.
|
||||
//
|
||||
// Originally we relied on not registering the master, on the fact that the
|
||||
// master was Unschedulable, and on static manifests for master components.
|
||||
// But we now do register masters in many environments, are generally moving
|
||||
// away from static manifests (for better manageability), and working towards
|
||||
// deprecating the unschedulable field (replacing it with taints & tolerations
|
||||
// instead).
|
||||
//
|
||||
// Even with tainting, a label remains the easiest way of making a positive
|
||||
// selection, so that pods can schedule only to master nodes for example, and
|
||||
// thus installations will likely define a label for their master nodes.
|
||||
//
|
||||
// So that we can recognize master nodes in consequent places though (such as
|
||||
// kubectl get nodes), we encourage installations to use the well-known labels.
|
||||
// We define NodeLabelRole, which is the preferred form, but we will also recognize
|
||||
// other forms that are known to be in widespread use (NodeLabelKubeadmAlphaRole).
|
||||
|
||||
const (
|
||||
// NodeLabelKubeadmAlphaRole is a label that kubeadm applies to a Node as a hint that it has a particular purpose.
|
||||
// Use of NodeLabelRole is preferred.
|
||||
NodeLabelKubeadmAlphaRole = "kubeadm.alpha.kubernetes.io/role"
|
||||
)
|
||||
249
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/zz_generated.deepcopy.go
generated
vendored
Normal file
249
vendor/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/zz_generated.deepcopy.go
generated
vendored
Normal file
|
|
@ -0,0 +1,249 @@
|
|||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright 2017 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.
|
||||
*/
|
||||
|
||||
// This file was autogenerated by deepcopy-gen. Do not edit it manually!
|
||||
|
||||
package kubeadm
|
||||
|
||||
import (
|
||||
conversion "k8s.io/apimachinery/pkg/conversion"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(RegisterDeepCopies)
|
||||
}
|
||||
|
||||
// RegisterDeepCopies adds deep-copy functions to the given scheme. Public
|
||||
// to allow building arbitrary schemes.
|
||||
//
|
||||
// Deprecated: deepcopy registration will go away when static deepcopy is fully implemented.
|
||||
func RegisterDeepCopies(scheme *runtime.Scheme) error {
|
||||
return scheme.AddGeneratedDeepCopyFuncs(
|
||||
conversion.GeneratedDeepCopyFunc{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
in.(*API).DeepCopyInto(out.(*API))
|
||||
return nil
|
||||
}, InType: reflect.TypeOf(&API{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
in.(*Etcd).DeepCopyInto(out.(*Etcd))
|
||||
return nil
|
||||
}, InType: reflect.TypeOf(&Etcd{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
in.(*MasterConfiguration).DeepCopyInto(out.(*MasterConfiguration))
|
||||
return nil
|
||||
}, InType: reflect.TypeOf(&MasterConfiguration{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
in.(*Networking).DeepCopyInto(out.(*Networking))
|
||||
return nil
|
||||
}, InType: reflect.TypeOf(&Networking{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
in.(*NodeConfiguration).DeepCopyInto(out.(*NodeConfiguration))
|
||||
return nil
|
||||
}, InType: reflect.TypeOf(&NodeConfiguration{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
in.(*TokenDiscovery).DeepCopyInto(out.(*TokenDiscovery))
|
||||
return nil
|
||||
}, InType: reflect.TypeOf(&TokenDiscovery{})},
|
||||
)
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *API) DeepCopyInto(out *API) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new API.
|
||||
func (in *API) DeepCopy() *API {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(API)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Etcd) DeepCopyInto(out *Etcd) {
|
||||
*out = *in
|
||||
if in.Endpoints != nil {
|
||||
in, out := &in.Endpoints, &out.Endpoints
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.ExtraArgs != nil {
|
||||
in, out := &in.ExtraArgs, &out.ExtraArgs
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Etcd.
|
||||
func (in *Etcd) DeepCopy() *Etcd {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Etcd)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *MasterConfiguration) DeepCopyInto(out *MasterConfiguration) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
out.API = in.API
|
||||
in.Etcd.DeepCopyInto(&out.Etcd)
|
||||
out.Networking = in.Networking
|
||||
if in.AuthorizationModes != nil {
|
||||
in, out := &in.AuthorizationModes, &out.AuthorizationModes
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
out.TokenTTL = in.TokenTTL
|
||||
if in.APIServerExtraArgs != nil {
|
||||
in, out := &in.APIServerExtraArgs, &out.APIServerExtraArgs
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.ControllerManagerExtraArgs != nil {
|
||||
in, out := &in.ControllerManagerExtraArgs, &out.ControllerManagerExtraArgs
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.SchedulerExtraArgs != nil {
|
||||
in, out := &in.SchedulerExtraArgs, &out.SchedulerExtraArgs
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.APIServerCertSANs != nil {
|
||||
in, out := &in.APIServerCertSANs, &out.APIServerCertSANs
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.FeatureGates != nil {
|
||||
in, out := &in.FeatureGates, &out.FeatureGates
|
||||
*out = make(map[string]bool, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MasterConfiguration.
|
||||
func (in *MasterConfiguration) DeepCopy() *MasterConfiguration {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(MasterConfiguration)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *MasterConfiguration) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Networking) DeepCopyInto(out *Networking) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Networking.
|
||||
func (in *Networking) DeepCopy() *Networking {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Networking)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *NodeConfiguration) DeepCopyInto(out *NodeConfiguration) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
if in.DiscoveryTokenAPIServers != nil {
|
||||
in, out := &in.DiscoveryTokenAPIServers, &out.DiscoveryTokenAPIServers
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.DiscoveryTokenCACertHashes != nil {
|
||||
in, out := &in.DiscoveryTokenCACertHashes, &out.DiscoveryTokenCACertHashes
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeConfiguration.
|
||||
func (in *NodeConfiguration) DeepCopy() *NodeConfiguration {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(NodeConfiguration)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *NodeConfiguration) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *TokenDiscovery) DeepCopyInto(out *TokenDiscovery) {
|
||||
*out = *in
|
||||
if in.Addresses != nil {
|
||||
in, out := &in.Addresses, &out.Addresses
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TokenDiscovery.
|
||||
func (in *TokenDiscovery) DeepCopy() *TokenDiscovery {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(TokenDiscovery)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
108
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/BUILD
generated
vendored
Normal file
108
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"cmd.go",
|
||||
"completion.go",
|
||||
"config.go",
|
||||
"init.go",
|
||||
"join.go",
|
||||
"reset.go",
|
||||
"token.go",
|
||||
"version.go",
|
||||
],
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||
"//cmd/kubeadm/app/apis/kubeadm/v1alpha1:go_default_library",
|
||||
"//cmd/kubeadm/app/apis/kubeadm/validation:go_default_library",
|
||||
"//cmd/kubeadm/app/cmd/phases:go_default_library",
|
||||
"//cmd/kubeadm/app/cmd/upgrade:go_default_library",
|
||||
"//cmd/kubeadm/app/cmd/util:go_default_library",
|
||||
"//cmd/kubeadm/app/constants:go_default_library",
|
||||
"//cmd/kubeadm/app/discovery:go_default_library",
|
||||
"//cmd/kubeadm/app/features:go_default_library",
|
||||
"//cmd/kubeadm/app/images:go_default_library",
|
||||
"//cmd/kubeadm/app/node:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/addons/dns:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/addons/proxy:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/apiconfig:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/bootstraptoken/clusterinfo:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/bootstraptoken/node:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/certs:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/certs/pkiutil:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/controlplane:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/etcd:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/kubeconfig:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/markmaster:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/selfhosting:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/uploadconfig:go_default_library",
|
||||
"//cmd/kubeadm/app/preflight:go_default_library",
|
||||
"//cmd/kubeadm/app/util:go_default_library",
|
||||
"//cmd/kubeadm/app/util/apiclient:go_default_library",
|
||||
"//cmd/kubeadm/app/util/config:go_default_library",
|
||||
"//cmd/kubeadm/app/util/dryrun:go_default_library",
|
||||
"//cmd/kubeadm/app/util/kubeconfig:go_default_library",
|
||||
"//cmd/kubeadm/app/util/pubkeypin:go_default_library",
|
||||
"//cmd/kubeadm/app/util/token:go_default_library",
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/bootstrap/api:go_default_library",
|
||||
"//pkg/kubectl/cmd/util:go_default_library",
|
||||
"//pkg/kubectl/util/i18n:go_default_library",
|
||||
"//pkg/printers:go_default_library",
|
||||
"//pkg/util/initsystem:go_default_library",
|
||||
"//pkg/util/node:go_default_library",
|
||||
"//pkg/util/version:go_default_library",
|
||||
"//pkg/version:go_default_library",
|
||||
"//vendor/github.com/ghodss/yaml:go_default_library",
|
||||
"//vendor/github.com/renstrom/dedent:go_default_library",
|
||||
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/fields:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/version:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/util/flag:go_default_library",
|
||||
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
||||
"//vendor/k8s.io/client-go/util/cert:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"reset_test.go",
|
||||
"token_test.go",
|
||||
],
|
||||
library = ":go_default_library",
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/constants:go_default_library",
|
||||
"//cmd/kubeadm/app/preflight:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//cmd/kubeadm/app/cmd/phases:all-srcs",
|
||||
"//cmd/kubeadm/app/cmd/upgrade:all-srcs",
|
||||
"//cmd/kubeadm/app/cmd/util:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
89
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/cmd.go
generated
vendored
Normal file
89
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/cmd.go
generated
vendored
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
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 cmd
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/renstrom/dedent"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"k8s.io/apiserver/pkg/util/flag"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/upgrade"
|
||||
)
|
||||
|
||||
func NewKubeadmCommand(_ io.Reader, out, err io.Writer) *cobra.Command {
|
||||
cmds := &cobra.Command{
|
||||
Use: "kubeadm",
|
||||
Short: "kubeadm: easily bootstrap a secure Kubernetes cluster",
|
||||
Long: dedent.Dedent(`
|
||||
kubeadm: easily bootstrap a secure Kubernetes cluster.
|
||||
|
||||
┌──────────────────────────────────────────────────────────┐
|
||||
│ KUBEADM IS BETA, DO NOT USE IT FOR PRODUCTION CLUSTERS! │
|
||||
│ │
|
||||
│ But, please try it out! Give us feedback at: │
|
||||
│ https://github.com/kubernetes/kubeadm/issues │
|
||||
│ and at-mention @kubernetes/sig-cluster-lifecycle-bugs │
|
||||
│ or @kubernetes/sig-cluster-lifecycle-feature-requests │
|
||||
└──────────────────────────────────────────────────────────┘
|
||||
|
||||
Example usage:
|
||||
|
||||
Create a two-machine cluster with one master (which controls the cluster),
|
||||
and one node (where your workloads, like Pods and Deployments run).
|
||||
|
||||
┌──────────────────────────────────────────────────────────┐
|
||||
│ On the first machine │
|
||||
├──────────────────────────────────────────────────────────┤
|
||||
│ master# kubeadm init │
|
||||
└──────────────────────────────────────────────────────────┘
|
||||
|
||||
┌──────────────────────────────────────────────────────────┐
|
||||
│ On the second machine │
|
||||
├──────────────────────────────────────────────────────────┤
|
||||
│ node# kubeadm join <arguments-returned-from-init> │
|
||||
└──────────────────────────────────────────────────────────┘
|
||||
|
||||
You can then repeat the second step on as many other machines as you like.
|
||||
|
||||
`),
|
||||
}
|
||||
|
||||
cmds.ResetFlags()
|
||||
cmds.SetGlobalNormalizationFunc(flag.WarnWordSepNormalizeFunc)
|
||||
|
||||
cmds.AddCommand(NewCmdCompletion(out, ""))
|
||||
cmds.AddCommand(NewCmdConfig(out))
|
||||
cmds.AddCommand(NewCmdInit(out))
|
||||
cmds.AddCommand(NewCmdJoin(out))
|
||||
cmds.AddCommand(NewCmdReset(out))
|
||||
cmds.AddCommand(NewCmdVersion(out))
|
||||
cmds.AddCommand(NewCmdToken(out, err))
|
||||
cmds.AddCommand(upgrade.NewCmdUpgrade(out))
|
||||
|
||||
// Wrap not yet fully supported commands in an alpha subcommand
|
||||
experimentalCmd := &cobra.Command{
|
||||
Use: "alpha",
|
||||
Short: "Experimental sub-commands not yet fully functional.",
|
||||
}
|
||||
experimentalCmd.AddCommand(phases.NewCmdPhase(out))
|
||||
cmds.AddCommand(experimentalCmd)
|
||||
|
||||
return cmds
|
||||
}
|
||||
293
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/completion.go
generated
vendored
Normal file
293
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/completion.go
generated
vendored
Normal file
|
|
@ -0,0 +1,293 @@
|
|||
/*
|
||||
Copyright 2017 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 cmd
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/renstrom/dedent"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||
)
|
||||
|
||||
const defaultBoilerPlate = `
|
||||
# Copyright 2017 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.
|
||||
`
|
||||
|
||||
var (
|
||||
completion_long = dedent.Dedent(`
|
||||
Output shell completion code for the specified shell (bash or zsh).
|
||||
The shell code must be evalutated to provide interactive
|
||||
completion of kubeadm commands. This can be done by sourcing it from
|
||||
the .bash_profile.
|
||||
|
||||
Note: this requires the bash-completion framework, which is not installed
|
||||
by default on Mac. This can be installed by using homebrew:
|
||||
|
||||
$ brew install bash-completion
|
||||
|
||||
Once installed, bash_completion must be evaluated. This can be done by adding the
|
||||
following line to the .bash_profile
|
||||
|
||||
$ source $(brew --prefix)/etc/bash_completion
|
||||
|
||||
Note for zsh users: [1] zsh completions are only supported in versions of zsh >= 5.2`)
|
||||
|
||||
completion_example = dedent.Dedent(`
|
||||
# Install bash completion on a Mac using homebrew
|
||||
brew install bash-completion
|
||||
printf "\n# Bash completion support\nsource $(brew --prefix)/etc/bash_completion\n" >> $HOME/.bash_profile
|
||||
source $HOME/.bash_profile
|
||||
|
||||
# Load the kubeadm completion code for bash into the current shell
|
||||
source <(kubeadm completion bash)
|
||||
|
||||
# Write bash completion code to a file and source if from .bash_profile
|
||||
kubeadm completion bash > ~/.kube/kubeadm_completion.bash.inc
|
||||
printf "\n# Kubeadm shell completion\nsource '$HOME/.kube/kubeadm_completion.bash.inc'\n" >> $HOME/.bash_profile
|
||||
source $HOME/.bash_profile
|
||||
|
||||
# Load the kubeadm completion code for zsh[1] into the current shell
|
||||
source <(kubeadm completion zsh)`)
|
||||
)
|
||||
|
||||
var (
|
||||
completion_shells = map[string]func(out io.Writer, cmd *cobra.Command) error{
|
||||
"bash": runCompletionBash,
|
||||
"zsh": runCompletionZsh,
|
||||
}
|
||||
)
|
||||
|
||||
func NewCmdCompletion(out io.Writer, boilerPlate string) *cobra.Command {
|
||||
shells := []string{}
|
||||
for s := range completion_shells {
|
||||
shells = append(shells, s)
|
||||
}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "completion SHELL",
|
||||
Short: i18n.T("Output shell completion code for the specified shell (bash or zsh)"),
|
||||
Long: completion_long,
|
||||
Example: completion_example,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
err := RunCompletion(out, boilerPlate, cmd, args)
|
||||
kubeadmutil.CheckErr(err)
|
||||
},
|
||||
ValidArgs: shells,
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func RunCompletion(out io.Writer, boilerPlate string, cmd *cobra.Command, args []string) error {
|
||||
if len(args) == 0 {
|
||||
return fmt.Errorf("shell not specified.")
|
||||
}
|
||||
if len(args) > 1 {
|
||||
return fmt.Errorf("too many arguments. expected only the shell type.")
|
||||
}
|
||||
run, found := completion_shells[args[0]]
|
||||
if !found {
|
||||
return fmt.Errorf("unsupported shell type %q.", args[0])
|
||||
}
|
||||
|
||||
if len(boilerPlate) == 0 {
|
||||
boilerPlate = defaultBoilerPlate
|
||||
}
|
||||
if _, err := out.Write([]byte(boilerPlate)); err != nil {
|
||||
return err
|
||||
}
|
||||
return run(out, cmd.Parent())
|
||||
}
|
||||
|
||||
func runCompletionBash(out io.Writer, kubeadm *cobra.Command) error {
|
||||
return kubeadm.GenBashCompletion(out)
|
||||
}
|
||||
|
||||
func runCompletionZsh(out io.Writer, kubeadm *cobra.Command) error {
|
||||
zsh_initialization := `
|
||||
__kubeadm_bash_source() {
|
||||
alias shopt=':'
|
||||
alias _expand=_bash_expand
|
||||
alias _complete=_bash_comp
|
||||
emulate -L sh
|
||||
setopt kshglob noshglob braceexpand
|
||||
|
||||
source "$@"
|
||||
}
|
||||
|
||||
__kubeadm_type() {
|
||||
# -t is not supported by zsh
|
||||
if [ "$1" == "-t" ]; then
|
||||
shift
|
||||
|
||||
# fake Bash 4 to disable "complete -o nospace". Instead
|
||||
# "compopt +-o nospace" is used in the code to toggle trailing
|
||||
# spaces. We don't support that, but leave trailing spaces on
|
||||
# all the time
|
||||
if [ "$1" = "__kubeadm_compopt" ]; then
|
||||
echo builtin
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
type "$@"
|
||||
}
|
||||
|
||||
__kubeadm_compgen() {
|
||||
local completions w
|
||||
completions=( $(compgen "$@") ) || return $?
|
||||
|
||||
# filter by given word as prefix
|
||||
while [[ "$1" = -* && "$1" != -- ]]; do
|
||||
shift
|
||||
shift
|
||||
done
|
||||
if [[ "$1" == -- ]]; then
|
||||
shift
|
||||
fi
|
||||
for w in "${completions[@]}"; do
|
||||
if [[ "${w}" = "$1"* ]]; then
|
||||
echo "${w}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
__kubeadm_compopt() {
|
||||
true # don't do anything. Not supported by bashcompinit in zsh
|
||||
}
|
||||
|
||||
__kubeadm_ltrim_colon_completions()
|
||||
{
|
||||
if [[ "$1" == *:* && "$COMP_WORDBREAKS" == *:* ]]; then
|
||||
# Remove colon-word prefix from COMPREPLY items
|
||||
local colon_word=${1%${1##*:}}
|
||||
local i=${#COMPREPLY[*]}
|
||||
while [[ $((--i)) -ge 0 ]]; do
|
||||
COMPREPLY[$i]=${COMPREPLY[$i]#"$colon_word"}
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
__kubeadm_get_comp_words_by_ref() {
|
||||
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
prev="${COMP_WORDS[${COMP_CWORD}-1]}"
|
||||
words=("${COMP_WORDS[@]}")
|
||||
cword=("${COMP_CWORD[@]}")
|
||||
}
|
||||
|
||||
__kubeadm_filedir() {
|
||||
local RET OLD_IFS w qw
|
||||
|
||||
__debug "_filedir $@ cur=$cur"
|
||||
if [[ "$1" = \~* ]]; then
|
||||
# somehow does not work. Maybe, zsh does not call this at all
|
||||
eval echo "$1"
|
||||
return 0
|
||||
fi
|
||||
|
||||
OLD_IFS="$IFS"
|
||||
IFS=$'\n'
|
||||
if [ "$1" = "-d" ]; then
|
||||
shift
|
||||
RET=( $(compgen -d) )
|
||||
else
|
||||
RET=( $(compgen -f) )
|
||||
fi
|
||||
IFS="$OLD_IFS"
|
||||
|
||||
IFS="," __debug "RET=${RET[@]} len=${#RET[@]}"
|
||||
|
||||
for w in ${RET[@]}; do
|
||||
if [[ ! "${w}" = "${cur}"* ]]; then
|
||||
continue
|
||||
fi
|
||||
if eval "[[ \"\${w}\" = *.$1 || -d \"\${w}\" ]]"; then
|
||||
qw="$(__kubeadm_quote "${w}")"
|
||||
if [ -d "${w}" ]; then
|
||||
COMPREPLY+=("${qw}/")
|
||||
else
|
||||
COMPREPLY+=("${qw}")
|
||||
fi
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
__kubeadm_quote() {
|
||||
if [[ $1 == \'* || $1 == \"* ]]; then
|
||||
# Leave out first character
|
||||
printf %q "${1:1}"
|
||||
else
|
||||
printf %q "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
autoload -U +X bashcompinit && bashcompinit
|
||||
|
||||
# use word boundary patterns for BSD or GNU sed
|
||||
LWORD='[[:<:]]'
|
||||
RWORD='[[:>:]]'
|
||||
if sed --help 2>&1 | grep -q GNU; then
|
||||
LWORD='\<'
|
||||
RWORD='\>'
|
||||
fi
|
||||
|
||||
__kubeadm_convert_bash_to_zsh() {
|
||||
sed \
|
||||
-e 's/declare -F/whence -w/' \
|
||||
-e 's/local \([a-zA-Z0-9_]*\)=/local \1; \1=/' \
|
||||
-e 's/flags+=("\(--.*\)=")/flags+=("\1"); two_word_flags+=("\1")/' \
|
||||
-e 's/must_have_one_flag+=("\(--.*\)=")/must_have_one_flag+=("\1")/' \
|
||||
-e "s/${LWORD}_filedir${RWORD}/__kubeadm_filedir/g" \
|
||||
-e "s/${LWORD}_get_comp_words_by_ref${RWORD}/__kubeadm_get_comp_words_by_ref/g" \
|
||||
-e "s/${LWORD}__ltrim_colon_completions${RWORD}/__kubeadm_ltrim_colon_completions/g" \
|
||||
-e "s/${LWORD}compgen${RWORD}/__kubeadm_compgen/g" \
|
||||
-e "s/${LWORD}compopt${RWORD}/__kubeadm_compopt/g" \
|
||||
-e "s/${LWORD}declare${RWORD}/builtin declare/g" \
|
||||
-e "s/\\\$(type${RWORD}/\$(__kubeadm_type/g" \
|
||||
<<'BASH_COMPLETION_EOF'
|
||||
`
|
||||
out.Write([]byte(zsh_initialization))
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
kubeadm.GenBashCompletion(buf)
|
||||
out.Write(buf.Bytes())
|
||||
|
||||
zsh_tail := `
|
||||
BASH_COMPLETION_EOF
|
||||
}
|
||||
|
||||
__kubeadm_bash_source <(__kubeadm_convert_bash_to_zsh)
|
||||
`
|
||||
out.Write([]byte(zsh_tail))
|
||||
return nil
|
||||
}
|
||||
188
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/config.go
generated
vendored
Normal file
188
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/config.go
generated
vendored
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
/*
|
||||
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 cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/renstrom/dedent"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
kubeadmapiext "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1"
|
||||
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/features"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/phases/uploadconfig"
|
||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||
configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config"
|
||||
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
)
|
||||
|
||||
func NewCmdConfig(out io.Writer) *cobra.Command {
|
||||
|
||||
var kubeConfigFile string
|
||||
cmd := &cobra.Command{
|
||||
Use: "config",
|
||||
Short: "Manage configuration for a kubeadm cluster persisted in a ConfigMap in the cluster.",
|
||||
Long: fmt.Sprintf(dedent.Dedent(`
|
||||
There is a ConfigMap in the %s namespace called %q that kubeadm uses to store internal configuration about the
|
||||
cluster. kubeadm CLI v1.8.0+ automatically creates this ConfigMap with used config on 'kubeadm init', but if you
|
||||
initialized your cluster using kubeadm v1.7.x or lower, you must use the 'config upload' command to create this
|
||||
ConfigMap in order for 'kubeadm upgrade' to be able to configure your upgraded cluster correctly.
|
||||
`), metav1.NamespaceSystem, constants.MasterConfigurationConfigMap),
|
||||
// Without this callback, if a user runs just the "upload"
|
||||
// command without a subcommand, or with an invalid subcommand,
|
||||
// cobra will print usage information, but still exit cleanly.
|
||||
// We want to return an error code in these cases so that the
|
||||
// user knows that their command was invalid.
|
||||
RunE: cmdutil.SubCmdRunE("config"),
|
||||
}
|
||||
|
||||
cmd.PersistentFlags().StringVar(&kubeConfigFile, "kubeconfig", "/etc/kubernetes/admin.conf", "The KubeConfig file to use for talking to the cluster")
|
||||
|
||||
cmd.AddCommand(NewCmdConfigUpload(out, &kubeConfigFile))
|
||||
cmd.AddCommand(NewCmdConfigView(out, &kubeConfigFile))
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func NewCmdConfigUpload(out io.Writer, kubeConfigFile *string) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "upload",
|
||||
Short: "Upload configuration about the current state so 'kubeadm upgrade' later can know how to configure the upgraded cluster",
|
||||
RunE: cmdutil.SubCmdRunE("upload"),
|
||||
}
|
||||
|
||||
cmd.AddCommand(NewCmdConfigUploadFromFile(out, kubeConfigFile))
|
||||
cmd.AddCommand(NewCmdConfigUploadFromFlags(out, kubeConfigFile))
|
||||
return cmd
|
||||
}
|
||||
|
||||
func NewCmdConfigView(out io.Writer, kubeConfigFile *string) *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "view",
|
||||
Short: "View the kubeadm configuration stored inside the cluster",
|
||||
Long: fmt.Sprintf(dedent.Dedent(`
|
||||
Using this command, you can view the ConfigMap in the cluster where the configuration for kubeadm is located
|
||||
|
||||
The configuration is located in the %q namespace in the %q ConfigMap
|
||||
`), metav1.NamespaceSystem, constants.MasterConfigurationConfigMap),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
client, err := kubeconfigutil.ClientSetFromFile(*kubeConfigFile)
|
||||
kubeadmutil.CheckErr(err)
|
||||
|
||||
err = RunConfigView(out, client)
|
||||
kubeadmutil.CheckErr(err)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func NewCmdConfigUploadFromFile(out io.Writer, kubeConfigFile *string) *cobra.Command {
|
||||
var cfgPath string
|
||||
cmd := &cobra.Command{
|
||||
Use: "from-file",
|
||||
Short: "Upload a configuration file to the in-cluster ConfigMap for kubeadm configuration",
|
||||
Long: fmt.Sprintf(dedent.Dedent(`
|
||||
Using from-file, you can upload configuration to the ConfigMap in the cluster using the same config file you gave to kubeadm init.
|
||||
If you initialized your cluster using a v1.7.x or lower kubeadm client and used the --config option; you need to run this command with the
|
||||
same config file before upgrading to v1.8 using 'kubeadm upgrade'.
|
||||
|
||||
The configuration is located in the %q namespace in the %q ConfigMap
|
||||
`), metav1.NamespaceSystem, constants.MasterConfigurationConfigMap),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if len(cfgPath) == 0 {
|
||||
kubeadmutil.CheckErr(fmt.Errorf("The --config flag is mandatory"))
|
||||
}
|
||||
|
||||
client, err := kubeconfigutil.ClientSetFromFile(*kubeConfigFile)
|
||||
kubeadmutil.CheckErr(err)
|
||||
|
||||
// The default configuration is empty; everything should come from the file on disk
|
||||
defaultcfg := &kubeadmapiext.MasterConfiguration{}
|
||||
// Upload the configuration using the file; don't care about the defaultcfg really
|
||||
err = uploadConfiguration(client, cfgPath, defaultcfg)
|
||||
kubeadmutil.CheckErr(err)
|
||||
},
|
||||
}
|
||||
cmd.Flags().StringVar(&cfgPath, "config", "", "Path to kubeadm config file (WARNING: Usage of a configuration file is experimental)")
|
||||
return cmd
|
||||
}
|
||||
|
||||
func NewCmdConfigUploadFromFlags(out io.Writer, kubeConfigFile *string) *cobra.Command {
|
||||
cfg := &kubeadmapiext.MasterConfiguration{}
|
||||
api.Scheme.Default(cfg)
|
||||
|
||||
var featureGatesString string
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "from-flags",
|
||||
Short: "Create the in-cluster configuration file for the first time from using flags",
|
||||
Long: fmt.Sprintf(dedent.Dedent(`
|
||||
Using from-flags, you can upload configuration to the ConfigMap in the cluster using the same flags you'd give to kubeadm init.
|
||||
If you initialized your cluster using a v1.7.x or lower kubeadm client and set some flag; you need to run this command with the
|
||||
same flags before upgrading to v1.8 using 'kubeadm upgrade'.
|
||||
|
||||
The configuration is located in the %q namespace in the %q ConfigMap
|
||||
`), metav1.NamespaceSystem, constants.MasterConfigurationConfigMap),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
var err error
|
||||
if cfg.FeatureGates, err = features.NewFeatureGate(&features.InitFeatureGates, featureGatesString); err != nil {
|
||||
kubeadmutil.CheckErr(err)
|
||||
}
|
||||
|
||||
client, err := kubeconfigutil.ClientSetFromFile(*kubeConfigFile)
|
||||
kubeadmutil.CheckErr(err)
|
||||
|
||||
// Default both statically and dynamically, convert to internal API type, and validate everything
|
||||
// The cfgPath argument is unset here as we shouldn't load a config file from disk, just go with cfg
|
||||
err = uploadConfiguration(client, "", cfg)
|
||||
kubeadmutil.CheckErr(err)
|
||||
},
|
||||
}
|
||||
AddInitConfigFlags(cmd.PersistentFlags(), cfg, &featureGatesString)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// RunConfigView gets the configuration persisted in the cluster
|
||||
func RunConfigView(out io.Writer, client clientset.Interface) error {
|
||||
|
||||
cfgConfigMap, err := client.CoreV1().ConfigMaps(metav1.NamespaceSystem).Get(constants.MasterConfigurationConfigMap, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// No need to append \n as that already exists in the ConfigMap
|
||||
fmt.Fprintf(out, "%s", cfgConfigMap.Data[constants.MasterConfigurationConfigMapKey])
|
||||
return nil
|
||||
}
|
||||
|
||||
// uploadConfiguration handles the uploading of the configuration internally
|
||||
func uploadConfiguration(client clientset.Interface, cfgPath string, defaultcfg *kubeadmapiext.MasterConfiguration) error {
|
||||
|
||||
// Default both statically and dynamically, convert to internal API type, and validate everything
|
||||
// First argument is unset here as we shouldn't load a config file from disk
|
||||
internalcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(cfgPath, defaultcfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Then just call the uploadconfig phase to do the rest of the work
|
||||
return uploadconfig.UploadConfiguration(internalcfg, client)
|
||||
}
|
||||
537
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/init.go
generated
vendored
Normal file
537
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/init.go
generated
vendored
Normal file
|
|
@ -0,0 +1,537 @@
|
|||
/*
|
||||
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 cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"text/template"
|
||||
"time"
|
||||
|
||||
"github.com/renstrom/dedent"
|
||||
"github.com/spf13/cobra"
|
||||
flag "github.com/spf13/pflag"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
kubeadmapiext "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation"
|
||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/features"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/images"
|
||||
dnsaddonphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/dns"
|
||||
proxyaddonphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/proxy"
|
||||
apiconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/apiconfig"
|
||||
clusterinfophase "k8s.io/kubernetes/cmd/kubeadm/app/phases/bootstraptoken/clusterinfo"
|
||||
nodebootstraptokenphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/bootstraptoken/node"
|
||||
certsphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/phases/certs/pkiutil"
|
||||
controlplanephase "k8s.io/kubernetes/cmd/kubeadm/app/phases/controlplane"
|
||||
etcdphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/etcd"
|
||||
kubeconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig"
|
||||
markmasterphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/markmaster"
|
||||
selfhostingphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/selfhosting"
|
||||
uploadconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/uploadconfig"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/preflight"
|
||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient"
|
||||
configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config"
|
||||
dryrunutil "k8s.io/kubernetes/cmd/kubeadm/app/util/dryrun"
|
||||
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/util/pubkeypin"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/util/version"
|
||||
)
|
||||
|
||||
var (
|
||||
initDoneTempl = template.Must(template.New("init").Parse(dedent.Dedent(`
|
||||
Your Kubernetes master has initialized successfully!
|
||||
|
||||
To start using your cluster, you need to run (as a regular user):
|
||||
|
||||
mkdir -p $HOME/.kube
|
||||
sudo cp -i {{.KubeConfigPath}} $HOME/.kube/config
|
||||
sudo chown $(id -u):$(id -g) $HOME/.kube/config
|
||||
|
||||
You should now deploy a pod network to the cluster.
|
||||
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
|
||||
http://kubernetes.io/docs/admin/addons/
|
||||
|
||||
You can now join any number of machines by running the following on each node
|
||||
as root:
|
||||
|
||||
kubeadm join --token {{.Token}} {{.MasterHostPort}} --discovery-token-ca-cert-hash {{.CAPubKeyPin}}
|
||||
|
||||
`)))
|
||||
|
||||
kubeletFailTempl = template.Must(template.New("init").Parse(dedent.Dedent(`
|
||||
Unfortunately, an error has occurred:
|
||||
{{ .Error }}
|
||||
|
||||
This error is likely caused by that:
|
||||
- The kubelet is not running
|
||||
- The kubelet is unhealthy due to a misconfiguration of the node in some way (required cgroups disabled)
|
||||
- There is no internet connection; so the kubelet can't pull the following control plane images:
|
||||
- {{ .APIServerImage }}
|
||||
- {{ .ControllerManagerImage }}
|
||||
- {{ .SchedulerImage }}
|
||||
|
||||
You can troubleshoot this for example with the following commands if you're on a systemd-powered system:
|
||||
- 'systemctl status kubelet'
|
||||
- 'journalctl -xeu kubelet'
|
||||
`)))
|
||||
)
|
||||
|
||||
// NewCmdInit returns "kubeadm init" command.
|
||||
func NewCmdInit(out io.Writer) *cobra.Command {
|
||||
cfg := &kubeadmapiext.MasterConfiguration{}
|
||||
api.Scheme.Default(cfg)
|
||||
|
||||
var cfgPath string
|
||||
var skipPreFlight bool
|
||||
var skipTokenPrint bool
|
||||
var dryRun bool
|
||||
var featureGatesString string
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "init",
|
||||
Short: "Run this in order to set up the Kubernetes master",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
var err error
|
||||
if cfg.FeatureGates, err = features.NewFeatureGate(&features.InitFeatureGates, featureGatesString); err != nil {
|
||||
kubeadmutil.CheckErr(err)
|
||||
}
|
||||
|
||||
api.Scheme.Default(cfg)
|
||||
internalcfg := &kubeadmapi.MasterConfiguration{}
|
||||
api.Scheme.Convert(cfg, internalcfg, nil)
|
||||
|
||||
i, err := NewInit(cfgPath, internalcfg, skipPreFlight, skipTokenPrint, dryRun)
|
||||
kubeadmutil.CheckErr(err)
|
||||
kubeadmutil.CheckErr(i.Validate(cmd))
|
||||
|
||||
// TODO: remove this warning in 1.9
|
||||
if !cmd.Flags().Lookup("token-ttl").Changed {
|
||||
fmt.Println("[kubeadm] WARNING: starting in 1.8, tokens expire after 24 hours by default (if you require a non-expiring token use --token-ttl 0)")
|
||||
}
|
||||
|
||||
kubeadmutil.CheckErr(i.Run(out))
|
||||
},
|
||||
}
|
||||
|
||||
AddInitConfigFlags(cmd.PersistentFlags(), cfg, &featureGatesString)
|
||||
AddInitOtherFlags(cmd.PersistentFlags(), &cfgPath, &skipPreFlight, &skipTokenPrint, &dryRun)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
// AddInitConfigFlags adds init flags bound to the config to the specified flagset
|
||||
func AddInitConfigFlags(flagSet *flag.FlagSet, cfg *kubeadmapiext.MasterConfiguration, featureGatesString *string) {
|
||||
flagSet.StringVar(
|
||||
&cfg.API.AdvertiseAddress, "apiserver-advertise-address", cfg.API.AdvertiseAddress,
|
||||
"The IP address the API Server will advertise it's listening on. 0.0.0.0 means the default network interface's address.",
|
||||
)
|
||||
flagSet.Int32Var(
|
||||
&cfg.API.BindPort, "apiserver-bind-port", cfg.API.BindPort,
|
||||
"Port for the API Server to bind to",
|
||||
)
|
||||
flagSet.StringVar(
|
||||
&cfg.Networking.ServiceSubnet, "service-cidr", cfg.Networking.ServiceSubnet,
|
||||
"Use alternative range of IP address for service VIPs",
|
||||
)
|
||||
flagSet.StringVar(
|
||||
&cfg.Networking.PodSubnet, "pod-network-cidr", cfg.Networking.PodSubnet,
|
||||
"Specify range of IP addresses for the pod network; if set, the control plane will automatically allocate CIDRs for every node",
|
||||
)
|
||||
flagSet.StringVar(
|
||||
&cfg.Networking.DNSDomain, "service-dns-domain", cfg.Networking.DNSDomain,
|
||||
`Use alternative domain for services, e.g. "myorg.internal"`,
|
||||
)
|
||||
flagSet.StringVar(
|
||||
&cfg.KubernetesVersion, "kubernetes-version", cfg.KubernetesVersion,
|
||||
`Choose a specific Kubernetes version for the control plane`,
|
||||
)
|
||||
flagSet.StringVar(
|
||||
&cfg.CertificatesDir, "cert-dir", cfg.CertificatesDir,
|
||||
`The path where to save and store the certificates`,
|
||||
)
|
||||
flagSet.StringSliceVar(
|
||||
&cfg.APIServerCertSANs, "apiserver-cert-extra-sans", cfg.APIServerCertSANs,
|
||||
`Optional extra altnames to use for the API Server serving cert. Can be both IP addresses and dns names.`,
|
||||
)
|
||||
flagSet.StringVar(
|
||||
&cfg.NodeName, "node-name", cfg.NodeName,
|
||||
`Specify the node name`,
|
||||
)
|
||||
flagSet.StringVar(
|
||||
&cfg.Token, "token", cfg.Token,
|
||||
"The token to use for establishing bidirectional trust between nodes and masters.",
|
||||
)
|
||||
flagSet.DurationVar(
|
||||
&cfg.TokenTTL.Duration, "token-ttl", cfg.TokenTTL.Duration,
|
||||
"The duration before the bootstrap token is automatically deleted. 0 means 'never expires'.",
|
||||
)
|
||||
flagSet.StringVar(featureGatesString, "feature-gates", *featureGatesString, "A set of key=value pairs that describe feature gates for various features. "+
|
||||
"Options are:\n"+strings.Join(features.KnownFeatures(&features.InitFeatureGates), "\n"))
|
||||
}
|
||||
|
||||
// AddInitOtherFlags adds init flags that are not bound to a configuration file to the given flagset
|
||||
func AddInitOtherFlags(flagSet *flag.FlagSet, cfgPath *string, skipPreFlight, skipTokenPrint, dryRun *bool) {
|
||||
flagSet.StringVar(
|
||||
cfgPath, "config", *cfgPath,
|
||||
"Path to kubeadm config file (WARNING: Usage of a configuration file is experimental)",
|
||||
)
|
||||
// Note: All flags that are not bound to the cfg object should be whitelisted in cmd/kubeadm/app/apis/kubeadm/validation/validation.go
|
||||
flagSet.BoolVar(
|
||||
skipPreFlight, "skip-preflight-checks", *skipPreFlight,
|
||||
"Skip preflight checks normally run before modifying the system",
|
||||
)
|
||||
// Note: All flags that are not bound to the cfg object should be whitelisted in cmd/kubeadm/app/apis/kubeadm/validation/validation.go
|
||||
flagSet.BoolVar(
|
||||
skipTokenPrint, "skip-token-print", *skipTokenPrint,
|
||||
"Skip printing of the default bootstrap token generated by 'kubeadm init'",
|
||||
)
|
||||
// Note: All flags that are not bound to the cfg object should be whitelisted in cmd/kubeadm/app/apis/kubeadm/validation/validation.go
|
||||
flagSet.BoolVar(
|
||||
dryRun, "dry-run", *dryRun,
|
||||
"Don't apply any changes; just output what would be done",
|
||||
)
|
||||
}
|
||||
|
||||
func NewInit(cfgPath string, cfg *kubeadmapi.MasterConfiguration, skipPreFlight, skipTokenPrint, dryRun bool) (*Init, error) {
|
||||
|
||||
fmt.Println("[kubeadm] WARNING: kubeadm is in beta, please do not use it for production clusters.")
|
||||
|
||||
if cfgPath != "" {
|
||||
b, err := ioutil.ReadFile(cfgPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to read config from %q [%v]", cfgPath, err)
|
||||
}
|
||||
if err := runtime.DecodeInto(api.Codecs.UniversalDecoder(), b, cfg); err != nil {
|
||||
return nil, fmt.Errorf("unable to decode config from %q [%v]", cfgPath, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Set defaults dynamically that the API group defaulting can't (by fetching information from the internet, looking up network interfaces, etc.)
|
||||
err := configutil.SetInitDynamicDefaults(cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fmt.Printf("[init] Using Kubernetes version: %s\n", cfg.KubernetesVersion)
|
||||
fmt.Printf("[init] Using Authorization modes: %v\n", cfg.AuthorizationModes)
|
||||
|
||||
// Warn about the limitations with the current cloudprovider solution.
|
||||
if cfg.CloudProvider != "" {
|
||||
fmt.Println("[init] WARNING: For cloudprovider integrations to work --cloud-provider must be set for all kubelets in the cluster.")
|
||||
fmt.Println("\t(/etc/systemd/system/kubelet.service.d/10-kubeadm.conf should be edited for this purpose)")
|
||||
}
|
||||
|
||||
if !skipPreFlight {
|
||||
fmt.Println("[preflight] Running pre-flight checks")
|
||||
|
||||
if err := preflight.RunInitMasterChecks(cfg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Try to start the kubelet service in case it's inactive
|
||||
preflight.TryStartKubelet()
|
||||
} else {
|
||||
fmt.Println("[preflight] Skipping pre-flight checks")
|
||||
}
|
||||
|
||||
return &Init{cfg: cfg, skipTokenPrint: skipTokenPrint, dryRun: dryRun}, nil
|
||||
}
|
||||
|
||||
type Init struct {
|
||||
cfg *kubeadmapi.MasterConfiguration
|
||||
skipTokenPrint bool
|
||||
dryRun bool
|
||||
}
|
||||
|
||||
// Validate validates configuration passed to "kubeadm init"
|
||||
func (i *Init) Validate(cmd *cobra.Command) error {
|
||||
if err := validation.ValidateMixedArguments(cmd.Flags()); err != nil {
|
||||
return err
|
||||
}
|
||||
return validation.ValidateMasterConfiguration(i.cfg).ToAggregate()
|
||||
}
|
||||
|
||||
// Run executes master node provisioning, including certificates, needed static pod manifests, etc.
|
||||
func (i *Init) Run(out io.Writer) error {
|
||||
|
||||
k8sVersion, err := version.ParseSemantic(i.cfg.KubernetesVersion)
|
||||
if err != nil {
|
||||
return fmt.Errorf("couldn't parse kubernetes version %q: %v", i.cfg.KubernetesVersion, err)
|
||||
}
|
||||
|
||||
// Get directories to write files to; can be faked if we're dry-running
|
||||
realCertsDir := i.cfg.CertificatesDir
|
||||
certsDirToWriteTo, kubeConfigDir, manifestDir, err := getDirectoriesToUse(i.dryRun, i.cfg.CertificatesDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// certsDirToWriteTo is gonna equal cfg.CertificatesDir in the normal case, but gonna be a temp directory if dryrunning
|
||||
i.cfg.CertificatesDir = certsDirToWriteTo
|
||||
|
||||
adminKubeConfigPath := filepath.Join(kubeConfigDir, kubeadmconstants.AdminKubeConfigFileName)
|
||||
|
||||
if res, _ := certsphase.UsingExternalCA(i.cfg); !res {
|
||||
|
||||
// PHASE 1: Generate certificates
|
||||
if err := certsphase.CreatePKIAssets(i.cfg); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// PHASE 2: Generate kubeconfig files for the admin and the kubelet
|
||||
if err := kubeconfigphase.CreateInitKubeConfigFiles(kubeConfigDir, i.cfg); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
} else {
|
||||
fmt.Println("[externalca] No ca.key detected, but all other certificates are available, so using external CA mode. Will not generate certs or kubeconfig.")
|
||||
}
|
||||
|
||||
// Temporarily set cfg.CertificatesDir to the "real value" when writing controlplane manifests
|
||||
// This is needed for writing the right kind of manifests
|
||||
i.cfg.CertificatesDir = realCertsDir
|
||||
|
||||
// PHASE 3: Bootstrap the control plane
|
||||
if err := controlplanephase.CreateInitStaticPodManifestFiles(manifestDir, i.cfg); err != nil {
|
||||
return err
|
||||
}
|
||||
// Add etcd static pod spec only if external etcd is not configured
|
||||
if len(i.cfg.Etcd.Endpoints) == 0 {
|
||||
if err := etcdphase.CreateLocalEtcdStaticPodManifestFile(manifestDir, i.cfg); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Revert the earlier CertificatesDir assignment to the directory that can be written to
|
||||
i.cfg.CertificatesDir = certsDirToWriteTo
|
||||
|
||||
// If we're dry-running, print the generated manifests
|
||||
if err := printFilesIfDryRunning(i.dryRun, manifestDir); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Create a kubernetes client and wait for the API server to be healthy (if not dryrunning)
|
||||
client, err := createClient(i.cfg, i.dryRun)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// waiter holds the apiclient.Waiter implementation of choice, responsible for querying the API server in various ways and waiting for conditions to be fulfilled
|
||||
waiter := getWaiter(i.dryRun, client)
|
||||
|
||||
if err := waitForAPIAndKubelet(waiter); err != nil {
|
||||
ctx := map[string]string{
|
||||
"Error": fmt.Sprintf("%v", err),
|
||||
"APIServerImage": images.GetCoreImage(kubeadmconstants.KubeAPIServer, i.cfg.GetControlPlaneImageRepository(), i.cfg.KubernetesVersion, i.cfg.UnifiedControlPlaneImage),
|
||||
"ControllerManagerImage": images.GetCoreImage(kubeadmconstants.KubeControllerManager, i.cfg.GetControlPlaneImageRepository(), i.cfg.KubernetesVersion, i.cfg.UnifiedControlPlaneImage),
|
||||
"SchedulerImage": images.GetCoreImage(kubeadmconstants.KubeScheduler, i.cfg.GetControlPlaneImageRepository(), i.cfg.KubernetesVersion, i.cfg.UnifiedControlPlaneImage),
|
||||
}
|
||||
|
||||
kubeletFailTempl.Execute(out, ctx)
|
||||
|
||||
return fmt.Errorf("couldn't initialize a Kubernetes cluster")
|
||||
}
|
||||
|
||||
// Upload currently used configuration to the cluster
|
||||
// Note: This is done right in the beginning of cluster initialization; as we might want to make other phases
|
||||
// depend on centralized information from this source in the future
|
||||
if err := uploadconfigphase.UploadConfiguration(i.cfg, client); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// PHASE 4: Mark the master with the right label/taint
|
||||
if err := markmasterphase.MarkMaster(client, i.cfg.NodeName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// PHASE 5: Set up the node bootstrap tokens
|
||||
if !i.skipTokenPrint {
|
||||
fmt.Printf("[bootstraptoken] Using token: %s\n", i.cfg.Token)
|
||||
}
|
||||
|
||||
// Create the default node bootstrap token
|
||||
tokenDescription := "The default bootstrap token generated by 'kubeadm init'."
|
||||
if err := nodebootstraptokenphase.UpdateOrCreateToken(client, i.cfg.Token, false, i.cfg.TokenTTL.Duration, kubeadmconstants.DefaultTokenUsages, []string{kubeadmconstants.V18NodeBootstrapTokenAuthGroup}, tokenDescription); err != nil {
|
||||
return err
|
||||
}
|
||||
// Create RBAC rules that makes the bootstrap tokens able to post CSRs
|
||||
if err := nodebootstraptokenphase.AllowBootstrapTokensToPostCSRs(client, k8sVersion); err != nil {
|
||||
return err
|
||||
}
|
||||
// Create RBAC rules that makes the bootstrap tokens able to get their CSRs approved automatically
|
||||
if err := nodebootstraptokenphase.AutoApproveNodeBootstrapTokens(client, k8sVersion); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Create the cluster-info ConfigMap with the associated RBAC rules
|
||||
if err := clusterinfophase.CreateBootstrapConfigMapIfNotExists(client, adminKubeConfigPath); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := clusterinfophase.CreateClusterInfoRBACRules(client); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// PHASE 6: Install and deploy all addons, and configure things as necessary
|
||||
|
||||
if err := apiconfigphase.CreateRBACRules(client, k8sVersion); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := dnsaddonphase.EnsureDNSAddon(i.cfg, client); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := proxyaddonphase.EnsureProxyAddon(i.cfg, client); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// PHASE 7: Make the control plane self-hosted if feature gate is enabled
|
||||
if features.Enabled(i.cfg.FeatureGates, features.SelfHosting) {
|
||||
// Temporary control plane is up, now we create our self hosted control
|
||||
// plane components and remove the static manifests:
|
||||
fmt.Println("[self-hosted] Creating self-hosted control plane...")
|
||||
if err := selfhostingphase.CreateSelfHostedControlPlane(manifestDir, kubeConfigDir, i.cfg, client, waiter); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Exit earlier if we're dryrunning
|
||||
if i.dryRun {
|
||||
fmt.Println("[dryrun] Finished dry-running successfully; above are the resources that would be created.")
|
||||
return nil
|
||||
}
|
||||
|
||||
// Load the CA certificate from so we can pin its public key
|
||||
caCert, err := pkiutil.TryLoadCertFromDisk(i.cfg.CertificatesDir, kubeadmconstants.CACertAndKeyBaseName)
|
||||
|
||||
// Generate the Master host/port pair used by initDoneTempl
|
||||
masterHostPort, err := kubeadmutil.GetMasterHostPort(i.cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ctx := map[string]string{
|
||||
"KubeConfigPath": adminKubeConfigPath,
|
||||
"Token": i.cfg.Token,
|
||||
"CAPubKeyPin": pubkeypin.Hash(caCert),
|
||||
"MasterHostPort": masterHostPort,
|
||||
}
|
||||
if i.skipTokenPrint {
|
||||
ctx["Token"] = "<value withheld>"
|
||||
}
|
||||
|
||||
return initDoneTempl.Execute(out, ctx)
|
||||
}
|
||||
|
||||
// createClient creates a clientset.Interface object
|
||||
func createClient(cfg *kubeadmapi.MasterConfiguration, dryRun bool) (clientset.Interface, error) {
|
||||
if dryRun {
|
||||
// If we're dry-running; we should create a faked client that answers some GETs in order to be able to do the full init flow and just logs the rest of requests
|
||||
dryRunGetter := apiclient.NewInitDryRunGetter(cfg.NodeName, cfg.Networking.ServiceSubnet)
|
||||
return apiclient.NewDryRunClient(dryRunGetter, os.Stdout), nil
|
||||
}
|
||||
|
||||
// If we're acting for real, we should create a connection to the API server and wait for it to come up
|
||||
return kubeconfigutil.ClientSetFromFile(kubeadmconstants.GetAdminKubeConfigPath())
|
||||
}
|
||||
|
||||
// getDirectoriesToUse returns the (in order) certificates, kubeconfig and Static Pod manifest directories, followed by a possible error
|
||||
// This behaves differently when dry-running vs the normal flow
|
||||
func getDirectoriesToUse(dryRun bool, defaultPkiDir string) (string, string, string, error) {
|
||||
if dryRun {
|
||||
dryRunDir, err := ioutil.TempDir("", "kubeadm-init-dryrun")
|
||||
if err != nil {
|
||||
return "", "", "", fmt.Errorf("couldn't create a temporary directory: %v", err)
|
||||
}
|
||||
// Use the same temp dir for all
|
||||
return dryRunDir, dryRunDir, dryRunDir, nil
|
||||
}
|
||||
|
||||
return defaultPkiDir, kubeadmconstants.KubernetesDir, kubeadmconstants.GetStaticPodDirectory(), nil
|
||||
}
|
||||
|
||||
// printFilesIfDryRunning prints the Static Pod manifests to stdout and informs about the temporary directory to go and lookup
|
||||
func printFilesIfDryRunning(dryRun bool, manifestDir string) error {
|
||||
if !dryRun {
|
||||
return nil
|
||||
}
|
||||
|
||||
fmt.Printf("[dryrun] Wrote certificates, kubeconfig files and control plane manifests to %q\n", manifestDir)
|
||||
fmt.Println("[dryrun] Won't print certificates or kubeconfig files due to the sensitive nature of them")
|
||||
fmt.Printf("[dryrun] Please go and examine the %q directory for details about what would be written\n", manifestDir)
|
||||
|
||||
// Print the contents of the upgraded manifests and pretend like they were in /etc/kubernetes/manifests
|
||||
files := []dryrunutil.FileToPrint{}
|
||||
for _, component := range kubeadmconstants.MasterComponents {
|
||||
realPath := kubeadmconstants.GetStaticPodFilepath(component, manifestDir)
|
||||
outputPath := kubeadmconstants.GetStaticPodFilepath(component, kubeadmconstants.GetStaticPodDirectory())
|
||||
files = append(files, dryrunutil.NewFileToPrint(realPath, outputPath))
|
||||
}
|
||||
|
||||
return dryrunutil.PrintDryRunFiles(files, os.Stdout)
|
||||
}
|
||||
|
||||
// getWaiter gets the right waiter implementation for the right occasion
|
||||
func getWaiter(dryRun bool, client clientset.Interface) apiclient.Waiter {
|
||||
if dryRun {
|
||||
return dryrunutil.NewWaiter()
|
||||
}
|
||||
return apiclient.NewKubeWaiter(client, 30*time.Minute, os.Stdout)
|
||||
}
|
||||
|
||||
// waitForAPIAndKubelet waits primarily for the API server to come up. If that takes a long time, and the kubelet
|
||||
// /healthz and /healthz/syncloop endpoints continuously are unhealthy, kubeadm will error out after a period of
|
||||
// backoffing exponentially
|
||||
func waitForAPIAndKubelet(waiter apiclient.Waiter) error {
|
||||
errorChan := make(chan error)
|
||||
|
||||
fmt.Printf("[init] Waiting for the kubelet to boot up the control plane as Static Pods from directory %q\n", kubeadmconstants.GetStaticPodDirectory())
|
||||
fmt.Println("[init] This often takes around a minute; or longer if the control plane images have to be pulled.")
|
||||
|
||||
go func(errC chan error, waiter apiclient.Waiter) {
|
||||
// This goroutine can only make kubeadm init fail. If this check succeeds, it won't do anything special
|
||||
if err := waiter.WaitForHealthyKubelet(40*time.Second, "http://localhost:10255/healthz"); err != nil {
|
||||
errC <- err
|
||||
}
|
||||
}(errorChan, waiter)
|
||||
|
||||
go func(errC chan error, waiter apiclient.Waiter) {
|
||||
// This goroutine can only make kubeadm init fail. If this check succeeds, it won't do anything special
|
||||
if err := waiter.WaitForHealthyKubelet(60*time.Second, "http://localhost:10255/healthz/syncloop"); err != nil {
|
||||
errC <- err
|
||||
}
|
||||
}(errorChan, waiter)
|
||||
|
||||
go func(errC chan error, waiter apiclient.Waiter) {
|
||||
// This main goroutine sends whatever WaitForAPI returns (error or not) to the channel
|
||||
// This in order to continue on success (nil error), or just fail if
|
||||
errC <- waiter.WaitForAPI()
|
||||
}(errorChan, waiter)
|
||||
|
||||
// This call is blocking until one of the goroutines sends to errorChan
|
||||
return <-errorChan
|
||||
}
|
||||
247
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/join.go
generated
vendored
Normal file
247
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/join.go
generated
vendored
Normal file
|
|
@ -0,0 +1,247 @@
|
|||
/*
|
||||
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 cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/renstrom/dedent"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
certutil "k8s.io/client-go/util/cert"
|
||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
kubeadmapiext "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation"
|
||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/discovery"
|
||||
kubeadmnode "k8s.io/kubernetes/cmd/kubeadm/app/node"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/preflight"
|
||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
nodeutil "k8s.io/kubernetes/pkg/util/node"
|
||||
)
|
||||
|
||||
var (
|
||||
joinDoneMsgf = dedent.Dedent(`
|
||||
Node join complete:
|
||||
* Certificate signing request sent to master and response
|
||||
received.
|
||||
* Kubelet informed of new secure connection details.
|
||||
|
||||
Run 'kubectl get nodes' on the master to see this machine join.
|
||||
`)
|
||||
)
|
||||
|
||||
// NewCmdJoin returns "kubeadm join" command.
|
||||
func NewCmdJoin(out io.Writer) *cobra.Command {
|
||||
cfg := &kubeadmapiext.NodeConfiguration{}
|
||||
api.Scheme.Default(cfg)
|
||||
|
||||
var skipPreFlight bool
|
||||
var cfgPath string
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "join <flags> [DiscoveryTokenAPIServers]",
|
||||
Short: "Run this on any machine you wish to join an existing cluster",
|
||||
Long: dedent.Dedent(`
|
||||
When joining a kubeadm initialized cluster, we need to establish
|
||||
bidirectional trust. This is split into discovery (having the Node
|
||||
trust the Kubernetes Master) and TLS bootstrap (having the Kubernetes
|
||||
Master trust the Node).
|
||||
|
||||
There are 2 main schemes for discovery. The first is to use a shared
|
||||
token along with the IP address of the API server. The second is to
|
||||
provide a file (a subset of the standard kubeconfig file). This file
|
||||
can be a local file or downloaded via an HTTPS URL. The forms are
|
||||
kubeadm join --discovery-token abcdef.1234567890abcdef 1.2.3.4:6443,
|
||||
kubeadm join --discovery-file path/to/file.conf, or kubeadm join
|
||||
--discovery-file https://url/file.conf. Only one form can be used. If
|
||||
the discovery information is loaded from a URL, HTTPS must be used and
|
||||
the host installed CA bundle is used to verify the connection.
|
||||
|
||||
If you use a shared token for discovery, you should also pass the
|
||||
--discovery-token-ca-cert-hash flag to validate the public key of the
|
||||
root certificate authority (CA) presented by the Kubernetes Master. The
|
||||
value of this flag is specified as "<hash-type>:<hex-encoded-value>",
|
||||
where the supported hash type is "sha256". The hash is calculated over
|
||||
the bytes of the Subject Public Key Info (SPKI) object (as in RFC7469).
|
||||
This value is available in the output of "kubeadm init" or can be
|
||||
calcuated using standard tools. The --discovery-token-ca-cert-hash flag
|
||||
may be repeated multiple times to allow more than one public key.
|
||||
|
||||
If you cannot know the CA public key hash ahead of time, you can pass
|
||||
the --discovery-token-unsafe-skip-ca-verification flag to disable this
|
||||
verification. This weakens the kubeadm security model since other nodes
|
||||
can potentially impersonate the Kubernetes Master.
|
||||
|
||||
The TLS bootstrap mechanism is also driven via a shared token. This is
|
||||
used to temporarily authenticate with the Kubernetes Master to submit a
|
||||
certificate signing request (CSR) for a locally created key pair. By
|
||||
default kubeadm will set up the Kubernetes Master to automatically
|
||||
approve these signing requests. This token is passed in with the
|
||||
--tls-bootstrap-token abcdef.1234567890abcdef flag.
|
||||
|
||||
Often times the same token is used for both parts. In this case, the
|
||||
--token flag can be used instead of specifying each token individually.
|
||||
`),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cfg.DiscoveryTokenAPIServers = args
|
||||
|
||||
api.Scheme.Default(cfg)
|
||||
internalcfg := &kubeadmapi.NodeConfiguration{}
|
||||
api.Scheme.Convert(cfg, internalcfg, nil)
|
||||
|
||||
j, err := NewJoin(cfgPath, args, internalcfg, skipPreFlight)
|
||||
kubeadmutil.CheckErr(err)
|
||||
kubeadmutil.CheckErr(j.Validate(cmd))
|
||||
kubeadmutil.CheckErr(j.Run(out))
|
||||
},
|
||||
}
|
||||
|
||||
cmd.PersistentFlags().StringVar(
|
||||
&cfgPath, "config", cfgPath,
|
||||
"Path to kubeadm config file")
|
||||
|
||||
cmd.PersistentFlags().StringVar(
|
||||
&cfg.DiscoveryFile, "discovery-file", "",
|
||||
"A file or url from which to load cluster information")
|
||||
cmd.PersistentFlags().StringVar(
|
||||
&cfg.DiscoveryToken, "discovery-token", "",
|
||||
"A token used to validate cluster information fetched from the master")
|
||||
cmd.PersistentFlags().StringVar(
|
||||
&cfg.NodeName, "node-name", "",
|
||||
"Specify the node name")
|
||||
cmd.PersistentFlags().StringVar(
|
||||
&cfg.TLSBootstrapToken, "tls-bootstrap-token", "",
|
||||
"A token used for TLS bootstrapping")
|
||||
cmd.PersistentFlags().StringSliceVar(
|
||||
&cfg.DiscoveryTokenCACertHashes, "discovery-token-ca-cert-hash", []string{},
|
||||
"For token-based discovery, validate that the root CA public key matches this hash (format: \"<type>:<value>\").")
|
||||
cmd.PersistentFlags().BoolVar(
|
||||
&cfg.DiscoveryTokenUnsafeSkipCAVerification, "discovery-token-unsafe-skip-ca-verification", false,
|
||||
"For token-based discovery, allow joining without --discovery-token-ca-cert-hash pinning.")
|
||||
|
||||
cmd.PersistentFlags().StringVar(
|
||||
&cfg.Token, "token", "",
|
||||
"Use this token for both discovery-token and tls-bootstrap-token")
|
||||
|
||||
cmd.PersistentFlags().BoolVar(
|
||||
&skipPreFlight, "skip-preflight-checks", false,
|
||||
"Skip preflight checks normally run before modifying the system",
|
||||
)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
type Join struct {
|
||||
cfg *kubeadmapi.NodeConfiguration
|
||||
}
|
||||
|
||||
func NewJoin(cfgPath string, args []string, cfg *kubeadmapi.NodeConfiguration, skipPreFlight bool) (*Join, error) {
|
||||
fmt.Println("[kubeadm] WARNING: kubeadm is in beta, please do not use it for production clusters.")
|
||||
|
||||
if cfg.NodeName == "" {
|
||||
cfg.NodeName = nodeutil.GetHostname("")
|
||||
}
|
||||
|
||||
if cfgPath != "" {
|
||||
b, err := ioutil.ReadFile(cfgPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to read config from %q [%v]", cfgPath, err)
|
||||
}
|
||||
if err := runtime.DecodeInto(api.Codecs.UniversalDecoder(), b, cfg); err != nil {
|
||||
return nil, fmt.Errorf("unable to decode config from %q [%v]", cfgPath, err)
|
||||
}
|
||||
}
|
||||
|
||||
if !skipPreFlight {
|
||||
fmt.Println("[preflight] Running pre-flight checks")
|
||||
|
||||
// Then continue with the others...
|
||||
if err := preflight.RunJoinNodeChecks(cfg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Try to start the kubelet service in case it's inactive
|
||||
preflight.TryStartKubelet()
|
||||
} else {
|
||||
fmt.Println("[preflight] Skipping pre-flight checks")
|
||||
}
|
||||
|
||||
return &Join{cfg: cfg}, nil
|
||||
}
|
||||
|
||||
func (j *Join) Validate(cmd *cobra.Command) error {
|
||||
if err := validation.ValidateMixedArguments(cmd.PersistentFlags()); err != nil {
|
||||
return err
|
||||
}
|
||||
return validation.ValidateNodeConfiguration(j.cfg).ToAggregate()
|
||||
}
|
||||
|
||||
// Run executes worker node provisioning and tries to join an existing cluster.
|
||||
func (j *Join) Run(out io.Writer) error {
|
||||
cfg, err := discovery.For(j.cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
client, err := kubeconfigutil.KubeConfigToClientSet(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := kubeadmnode.ValidateAPIServer(client); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
kubeconfigFile := filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.KubeletBootstrapKubeConfigFileName)
|
||||
|
||||
// Depending on the kubelet version, we might perform the TLS bootstrap or not
|
||||
kubeletVersionBytes, err := exec.Command("sh", "-c", "kubelet --version").Output()
|
||||
// In case the command executed successfully and returned v1.7-something, we'll perform TLS Bootstrapping
|
||||
// Otherwise, just assume v1.8
|
||||
// TODO: In the beginning of the v1.9 cycle, we can remove the logic as we then don't support v1.7 anymore
|
||||
if err == nil && strings.HasPrefix(string(kubeletVersionBytes), "Kubernetes v1.7") {
|
||||
hostname := nodeutil.GetHostname(j.cfg.NodeName)
|
||||
if err := kubeadmnode.PerformTLSBootstrap(cfg, hostname); err != nil {
|
||||
return err
|
||||
}
|
||||
// As we now performed the TLS Bootstrap, change the filepath to be kubelet.conf instead of bootstrap-kubelet.conf
|
||||
kubeconfigFile = filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.KubeletKubeConfigFileName)
|
||||
}
|
||||
|
||||
// Write the bootstrap kubelet config file or the TLS-Boostrapped kubelet config file down to disk
|
||||
if err := kubeconfigutil.WriteToDisk(kubeconfigFile, cfg); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Write the ca certificate to disk so kubelet can use it for authentication
|
||||
cluster := cfg.Contexts[cfg.CurrentContext].Cluster
|
||||
err = certutil.WriteCert(j.cfg.CACertPath, cfg.Clusters[cluster].CertificateAuthorityData)
|
||||
if err != nil {
|
||||
return fmt.Errorf("couldn't save the CA certificate to disk: %v", err)
|
||||
}
|
||||
|
||||
fmt.Fprintf(out, joinDoneMsgf)
|
||||
return nil
|
||||
}
|
||||
89
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/BUILD
generated
vendored
Normal file
89
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"addons.go",
|
||||
"bootstraptoken.go",
|
||||
"certs.go",
|
||||
"controlplane.go",
|
||||
"etcd.go",
|
||||
"kubeconfig.go",
|
||||
"markmaster.go",
|
||||
"phase.go",
|
||||
"preflight.go",
|
||||
"selfhosting.go",
|
||||
"uploadconfig.go",
|
||||
"util.go",
|
||||
],
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||
"//cmd/kubeadm/app/apis/kubeadm/v1alpha1:go_default_library",
|
||||
"//cmd/kubeadm/app/apis/kubeadm/validation:go_default_library",
|
||||
"//cmd/kubeadm/app/cmd/util:go_default_library",
|
||||
"//cmd/kubeadm/app/constants:go_default_library",
|
||||
"//cmd/kubeadm/app/features:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/addons/dns:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/addons/proxy:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/bootstraptoken/clusterinfo:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/bootstraptoken/node:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/certs:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/controlplane:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/etcd:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/kubeconfig:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/markmaster:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/selfhosting:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/uploadconfig:go_default_library",
|
||||
"//cmd/kubeadm/app/preflight:go_default_library",
|
||||
"//cmd/kubeadm/app/util:go_default_library",
|
||||
"//cmd/kubeadm/app/util/apiclient:go_default_library",
|
||||
"//cmd/kubeadm/app/util/config:go_default_library",
|
||||
"//cmd/kubeadm/app/util/kubeconfig:go_default_library",
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/util/version:go_default_library",
|
||||
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"addons_test.go",
|
||||
"certs_test.go",
|
||||
"controlplane_test.go",
|
||||
"etcd_test.go",
|
||||
"kubeconfig_test.go",
|
||||
],
|
||||
library = ":go_default_library",
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||
"//cmd/kubeadm/app/apis/kubeadm/install:go_default_library",
|
||||
"//cmd/kubeadm/app/constants:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/certs/pkiutil:go_default_library",
|
||||
"//cmd/kubeadm/test:go_default_library",
|
||||
"//cmd/kubeadm/test/cmd:go_default_library",
|
||||
"//cmd/kubeadm/test/kubeconfig:go_default_library",
|
||||
"//pkg/util/node:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/clientcmd:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
150
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/addons.go
generated
vendored
Normal file
150
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/addons.go
generated
vendored
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
Copyright 2017 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 phases
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
kubeadmapiext "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation"
|
||||
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
|
||||
dnsaddon "k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/dns"
|
||||
proxyaddon "k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/proxy"
|
||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||
configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config"
|
||||
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
)
|
||||
|
||||
// NewCmdAddon returns the addon Cobra command
|
||||
func NewCmdAddon() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "addon <addon-name>",
|
||||
Aliases: []string{"addons"},
|
||||
Short: "Install an addon to a Kubernetes cluster.",
|
||||
RunE: cmdutil.SubCmdRunE("addon"),
|
||||
}
|
||||
|
||||
cmd.AddCommand(getAddonsSubCommands()...)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// EnsureAllAddons install all addons to a Kubernetes cluster.
|
||||
func EnsureAllAddons(cfg *kubeadmapi.MasterConfiguration, client clientset.Interface) error {
|
||||
|
||||
addonActions := []func(cfg *kubeadmapi.MasterConfiguration, client clientset.Interface) error{
|
||||
dnsaddon.EnsureDNSAddon,
|
||||
proxyaddon.EnsureProxyAddon,
|
||||
}
|
||||
|
||||
for _, action := range addonActions {
|
||||
err := action(cfg, client)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// getAddonsSubCommands returns sub commands for addons phase
|
||||
func getAddonsSubCommands() []*cobra.Command {
|
||||
cfg := &kubeadmapiext.MasterConfiguration{}
|
||||
// Default values for the cobra help text
|
||||
api.Scheme.Default(cfg)
|
||||
|
||||
var cfgPath, kubeConfigFile string
|
||||
var subCmds []*cobra.Command
|
||||
|
||||
subCmdProperties := []struct {
|
||||
use string
|
||||
short string
|
||||
cmdFunc func(cfg *kubeadmapi.MasterConfiguration, client clientset.Interface) error
|
||||
}{
|
||||
{
|
||||
use: "all",
|
||||
short: "Install all addons to a Kubernetes cluster",
|
||||
cmdFunc: EnsureAllAddons,
|
||||
},
|
||||
{
|
||||
use: "kube-dns",
|
||||
short: "Install the kube-dns addon to a Kubernetes cluster.",
|
||||
cmdFunc: dnsaddon.EnsureDNSAddon,
|
||||
},
|
||||
{
|
||||
use: "kube-proxy",
|
||||
short: "Install the kube-proxy addon to a Kubernetes cluster.",
|
||||
cmdFunc: proxyaddon.EnsureProxyAddon,
|
||||
},
|
||||
}
|
||||
|
||||
for _, properties := range subCmdProperties {
|
||||
// Creates the UX Command
|
||||
cmd := &cobra.Command{
|
||||
Use: properties.use,
|
||||
Short: properties.short,
|
||||
Run: runAddonsCmdFunc(properties.cmdFunc, cfg, &kubeConfigFile, &cfgPath),
|
||||
}
|
||||
|
||||
// Add flags to the command
|
||||
cmd.Flags().StringVar(&kubeConfigFile, "kubeconfig", "/etc/kubernetes/admin.conf", "The KubeConfig file to use for talking to the cluster")
|
||||
cmd.Flags().StringVar(&cfgPath, "config", cfgPath, "Path to kubeadm config file (WARNING: Usage of a configuration file is experimental)")
|
||||
cmd.Flags().StringVar(&cfg.KubernetesVersion, "kubernetes-version", cfg.KubernetesVersion, `Choose a specific Kubernetes version for the control plane.`)
|
||||
cmd.Flags().StringVar(&cfg.ImageRepository, "image-repository", cfg.ImageRepository, `Choose a container registry to pull control plane images from.`)
|
||||
|
||||
if properties.use == "all" || properties.use == "kube-proxy" {
|
||||
cmd.Flags().StringVar(&cfg.API.AdvertiseAddress, "apiserver-advertise-address", cfg.API.AdvertiseAddress, `The IP address the API Server will advertise it's listening on. 0.0.0.0 means the default network interface's address.`)
|
||||
cmd.Flags().Int32Var(&cfg.API.BindPort, "apiserver-bind-port", cfg.API.BindPort, `Port for the API Server to bind to.`)
|
||||
cmd.Flags().StringVar(&cfg.Networking.PodSubnet, "pod-network-cidr", cfg.Networking.PodSubnet, `Specify range of IP addresses for the pod network; if set, the control plane will automatically allocate CIDRs for every node.`)
|
||||
}
|
||||
|
||||
if properties.use == "all" || properties.use == "kube-dns" {
|
||||
cmd.Flags().StringVar(&cfg.Networking.DNSDomain, "service-dns-domain", cfg.Networking.DNSDomain, `Use alternative domain for services, e.g. "myorg.internal.`)
|
||||
}
|
||||
subCmds = append(subCmds, cmd)
|
||||
}
|
||||
|
||||
return subCmds
|
||||
}
|
||||
|
||||
// runAddonsCmdFunc creates a cobra.Command Run function, by composing the call to the given cmdFunc with necessary additional steps (e.g preparation of input parameters)
|
||||
func runAddonsCmdFunc(cmdFunc func(cfg *kubeadmapi.MasterConfiguration, client clientset.Interface) error, cfg *kubeadmapiext.MasterConfiguration, kubeConfigFile *string, cfgPath *string) func(cmd *cobra.Command, args []string) {
|
||||
|
||||
// the following statement build a clousure that wraps a call to a cmdFunc, binding
|
||||
// the function itself with the specific parameters of each sub command.
|
||||
// Please note that specific parameter should be passed as value, while other parameters - passed as reference -
|
||||
// are shared between sub commands and gets access to current value e.g. flags value.
|
||||
|
||||
return func(cmd *cobra.Command, args []string) {
|
||||
if err := validation.ValidateMixedArguments(cmd.Flags()); err != nil {
|
||||
kubeadmutil.CheckErr(err)
|
||||
}
|
||||
|
||||
internalcfg := &kubeadmapi.MasterConfiguration{}
|
||||
api.Scheme.Convert(cfg, internalcfg, nil)
|
||||
client, err := kubeconfigutil.ClientSetFromFile(*kubeConfigFile)
|
||||
kubeadmutil.CheckErr(err)
|
||||
internalcfg, err = configutil.ConfigFileAndDefaultsToInternalConfig(*cfgPath, cfg)
|
||||
kubeadmutil.CheckErr(err)
|
||||
|
||||
// Execute the cmdFunc
|
||||
err = cmdFunc(internalcfg, client)
|
||||
kubeadmutil.CheckErr(err)
|
||||
}
|
||||
}
|
||||
72
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/addons_test.go
generated
vendored
Normal file
72
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/addons_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
Copyright 2017 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 phases
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
// required for triggering api machinery startup when running unit tests
|
||||
_ "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/install"
|
||||
|
||||
cmdtestutil "k8s.io/kubernetes/cmd/kubeadm/test/cmd"
|
||||
)
|
||||
|
||||
func TestAddonsSubCommandsHasFlags(t *testing.T) {
|
||||
|
||||
subCmds := getAddonsSubCommands()
|
||||
|
||||
commonFlags := []string{
|
||||
"kubeconfig",
|
||||
"config",
|
||||
"kubernetes-version",
|
||||
"image-repository",
|
||||
}
|
||||
|
||||
var tests = []struct {
|
||||
command string
|
||||
additionalFlags []string
|
||||
}{
|
||||
{
|
||||
command: "all",
|
||||
additionalFlags: []string{
|
||||
"apiserver-advertise-address",
|
||||
"apiserver-bind-port",
|
||||
"pod-network-cidr",
|
||||
"service-dns-domain",
|
||||
},
|
||||
},
|
||||
{
|
||||
command: "kube-proxy",
|
||||
additionalFlags: []string{
|
||||
"apiserver-advertise-address",
|
||||
"apiserver-bind-port",
|
||||
"pod-network-cidr",
|
||||
},
|
||||
},
|
||||
{
|
||||
command: "kube-dns",
|
||||
additionalFlags: []string{
|
||||
"service-dns-domain",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
expectedFlags := append(commonFlags, test.additionalFlags...)
|
||||
cmdtestutil.AssertSubCommandHasFlags(t, subCmds, test.command, expectedFlags...)
|
||||
}
|
||||
}
|
||||
143
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/bootstraptoken.go
generated
vendored
Normal file
143
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/bootstraptoken.go
generated
vendored
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
Copyright 2017 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 phases
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/phases/bootstraptoken/clusterinfo"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/phases/bootstraptoken/node"
|
||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
|
||||
versionutil "k8s.io/kubernetes/pkg/util/version"
|
||||
)
|
||||
|
||||
// NewCmdBootstrapToken returns the Cobra command for running the mark-master phase
|
||||
func NewCmdBootstrapToken() *cobra.Command {
|
||||
var kubeConfigFile string
|
||||
cmd := &cobra.Command{
|
||||
Use: "bootstrap-token",
|
||||
Short: "Manage kubeadm-specific Bootstrap Token functions.",
|
||||
Aliases: []string{"bootstraptoken"},
|
||||
RunE: cmdutil.SubCmdRunE("bootstrap-token"),
|
||||
}
|
||||
|
||||
cmd.PersistentFlags().StringVar(&kubeConfigFile, "kubeconfig", "/etc/kubernetes/admin.conf", "The KubeConfig file to use for talking to the cluster")
|
||||
|
||||
// Add subcommands
|
||||
cmd.AddCommand(NewSubCmdClusterInfo(&kubeConfigFile))
|
||||
cmd.AddCommand(NewSubCmdNodeBootstrapToken(&kubeConfigFile))
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
// NewSubCmdClusterInfo returns the Cobra command for running the cluster-info sub-phase
|
||||
func NewSubCmdClusterInfo(kubeConfigFile *string) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "cluster-info <clusterinfo-file>",
|
||||
Short: "Uploads and exposes the cluster-info ConfigMap publicly from the given cluster-info file",
|
||||
Aliases: []string{"clusterinfo"},
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
err := cmdutil.ValidateExactArgNumber(args, []string{"clusterinfo-file"})
|
||||
kubeadmutil.CheckErr(err)
|
||||
|
||||
client, err := kubeconfigutil.ClientSetFromFile(*kubeConfigFile)
|
||||
kubeadmutil.CheckErr(err)
|
||||
|
||||
// Here it's safe to get args[0], since we've validated that the argument exists above in validateExactArgNumber
|
||||
clusterInfoFile := args[0]
|
||||
// Create the cluster-info ConfigMap or update if it already exists
|
||||
err = clusterinfo.CreateBootstrapConfigMapIfNotExists(client, clusterInfoFile)
|
||||
kubeadmutil.CheckErr(err)
|
||||
|
||||
// Create the RBAC rules that expose the cluster-info ConfigMap properly
|
||||
err = clusterinfo.CreateClusterInfoRBACRules(client)
|
||||
kubeadmutil.CheckErr(err)
|
||||
},
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
// NewSubCmdNodeBootstrapToken returns the Cobra command for running the node sub-phase
|
||||
func NewSubCmdNodeBootstrapToken(kubeConfigFile *string) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "node",
|
||||
Short: "Manages Node Bootstrap Tokens",
|
||||
Aliases: []string{"clusterinfo"},
|
||||
RunE: cmdutil.SubCmdRunE("node"),
|
||||
}
|
||||
|
||||
cmd.AddCommand(NewSubCmdNodeBootstrapTokenPostCSRs(kubeConfigFile))
|
||||
cmd.AddCommand(NewSubCmdNodeBootstrapTokenAutoApprove(kubeConfigFile))
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
// NewSubCmdNodeBootstrapTokenPostCSRs returns the Cobra command for running the allow-post-csrs sub-phase
|
||||
func NewSubCmdNodeBootstrapTokenPostCSRs(kubeConfigFile *string) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "allow-post-csrs",
|
||||
Short: "Configure RBAC to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
client, err := kubeconfigutil.ClientSetFromFile(*kubeConfigFile)
|
||||
kubeadmutil.CheckErr(err)
|
||||
|
||||
clusterVersion, err := getClusterVersion(client)
|
||||
kubeadmutil.CheckErr(err)
|
||||
|
||||
err = node.AllowBootstrapTokensToPostCSRs(client, clusterVersion)
|
||||
kubeadmutil.CheckErr(err)
|
||||
},
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
// NewSubCmdNodeBootstrapToken returns the Cobra command for running the allow-auto-approve sub-phase
|
||||
func NewSubCmdNodeBootstrapTokenAutoApprove(kubeConfigFile *string) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "allow-auto-approve",
|
||||
Short: "Configure RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
client, err := kubeconfigutil.ClientSetFromFile(*kubeConfigFile)
|
||||
kubeadmutil.CheckErr(err)
|
||||
|
||||
clusterVersion, err := getClusterVersion(client)
|
||||
kubeadmutil.CheckErr(err)
|
||||
|
||||
err = node.AutoApproveNodeBootstrapTokens(client, clusterVersion)
|
||||
kubeadmutil.CheckErr(err)
|
||||
},
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
// getClusterVersion fetches the API server version and parses it
|
||||
func getClusterVersion(client clientset.Interface) (*versionutil.Version, error) {
|
||||
clusterVersionInfo, err := client.Discovery().ServerVersion()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to check server version: %v", err)
|
||||
}
|
||||
clusterVersion, err := versionutil.ParseSemantic(clusterVersionInfo.String())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse server version: %v", err)
|
||||
}
|
||||
return clusterVersion, nil
|
||||
}
|
||||
150
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/certs.go
generated
vendored
Normal file
150
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/certs.go
generated
vendored
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
Copyright 2017 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 phases
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
kubeadmapiext "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation"
|
||||
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
|
||||
certsphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs"
|
||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||
configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
)
|
||||
|
||||
// NewCmdCerts return main command for certs phase
|
||||
func NewCmdCerts() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "certs",
|
||||
Aliases: []string{"certificates"},
|
||||
Short: "Generate certificates for a Kubernetes cluster.",
|
||||
RunE: cmdutil.SubCmdRunE("certs"),
|
||||
}
|
||||
|
||||
cmd.AddCommand(getCertsSubCommands("")...)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// getCertsSubCommands returns sub commands for certs phase
|
||||
func getCertsSubCommands(defaultKubernetesVersion string) []*cobra.Command {
|
||||
|
||||
cfg := &kubeadmapiext.MasterConfiguration{}
|
||||
|
||||
// This is used for unit testing only...
|
||||
// If we wouldn't set this to something, the code would dynamically look up the version from the internet
|
||||
// By setting this explicitely for tests workarounds that
|
||||
if defaultKubernetesVersion != "" {
|
||||
cfg.KubernetesVersion = defaultKubernetesVersion
|
||||
}
|
||||
|
||||
// Default values for the cobra help text
|
||||
api.Scheme.Default(cfg)
|
||||
|
||||
var cfgPath string
|
||||
var subCmds []*cobra.Command
|
||||
|
||||
subCmdProperties := []struct {
|
||||
use string
|
||||
short string
|
||||
cmdFunc func(cfg *kubeadmapi.MasterConfiguration) error
|
||||
}{
|
||||
{
|
||||
use: "all",
|
||||
short: "Generate all PKI assets necessary to establish the control plane",
|
||||
cmdFunc: certsphase.CreatePKIAssets,
|
||||
},
|
||||
{
|
||||
use: "ca",
|
||||
short: "Generate CA certificate and key for a Kubernetes cluster.",
|
||||
cmdFunc: certsphase.CreateCACertAndKeyfiles,
|
||||
},
|
||||
{
|
||||
use: "apiserver",
|
||||
short: "Generate API Server serving certificate and key.",
|
||||
cmdFunc: certsphase.CreateAPIServerCertAndKeyFiles,
|
||||
},
|
||||
{
|
||||
use: "apiserver-kubelet-client",
|
||||
short: "Generate a client certificate for the API Server to connect to the kubelets securely.",
|
||||
cmdFunc: certsphase.CreateAPIServerKubeletClientCertAndKeyFiles,
|
||||
},
|
||||
{
|
||||
use: "sa",
|
||||
short: "Generate a private key for signing service account tokens along with its public key.",
|
||||
cmdFunc: certsphase.CreateServiceAccountKeyAndPublicKeyFiles,
|
||||
},
|
||||
{
|
||||
use: "front-proxy-ca",
|
||||
short: "Generate front proxy CA certificate and key for a Kubernetes cluster.",
|
||||
cmdFunc: certsphase.CreateFrontProxyCACertAndKeyFiles,
|
||||
},
|
||||
{
|
||||
use: "front-proxy-client",
|
||||
short: "Generate front proxy CA client certificate and key for a Kubernetes cluster.",
|
||||
cmdFunc: certsphase.CreateFrontProxyClientCertAndKeyFiles,
|
||||
},
|
||||
}
|
||||
|
||||
for _, properties := range subCmdProperties {
|
||||
// Creates the UX Command
|
||||
cmd := &cobra.Command{
|
||||
Use: properties.use,
|
||||
Short: properties.short,
|
||||
Run: runCmdFunc(properties.cmdFunc, &cfgPath, cfg),
|
||||
}
|
||||
|
||||
// Add flags to the command
|
||||
cmd.Flags().StringVar(&cfgPath, "config", cfgPath, "Path to kubeadm config file (WARNING: Usage of a configuration file is experimental)")
|
||||
cmd.Flags().StringVar(&cfg.CertificatesDir, "cert-dir", cfg.CertificatesDir, "The path where to save and store the certificates")
|
||||
if properties.use == "all" || properties.use == "apiserver" {
|
||||
cmd.Flags().StringVar(&cfg.Networking.DNSDomain, "service-dns-domain", cfg.Networking.DNSDomain, "Use alternative domain for services, e.g. \"myorg.internal\"")
|
||||
cmd.Flags().StringVar(&cfg.Networking.ServiceSubnet, "service-cidr", cfg.Networking.ServiceSubnet, "Use alternative range of IP address for service VIPs")
|
||||
cmd.Flags().StringSliceVar(&cfg.APIServerCertSANs, "apiserver-cert-extra-sans", []string{}, "Optional extra altnames to use for the API Server serving cert. Can be both IP addresses and dns names.")
|
||||
cmd.Flags().StringVar(&cfg.API.AdvertiseAddress, "apiserver-advertise-address", cfg.API.AdvertiseAddress, "The IP address the API Server will advertise it's listening on. 0.0.0.0 means the default network interface's address.")
|
||||
}
|
||||
|
||||
subCmds = append(subCmds, cmd)
|
||||
}
|
||||
|
||||
return subCmds
|
||||
}
|
||||
|
||||
// runCmdFunc creates a cobra.Command Run function, by composing the call to the given cmdFunc with necessary additional steps (e.g preparation of input parameters)
|
||||
func runCmdFunc(cmdFunc func(cfg *kubeadmapi.MasterConfiguration) error, cfgPath *string, cfg *kubeadmapiext.MasterConfiguration) func(cmd *cobra.Command, args []string) {
|
||||
|
||||
// the following statement build a clousure that wraps a call to a cmdFunc, binding
|
||||
// the function itself with the specific parameters of each sub command.
|
||||
// Please note that specific parameter should be passed as value, while other parameters - passed as reference -
|
||||
// are shared between sub commands and gets access to current value e.g. flags value.
|
||||
|
||||
return func(cmd *cobra.Command, args []string) {
|
||||
if err := validation.ValidateMixedArguments(cmd.Flags()); err != nil {
|
||||
kubeadmutil.CheckErr(err)
|
||||
}
|
||||
|
||||
// This call returns the ready-to-use configuration based on the configuration file that might or might not exist and the default cfg populated by flags
|
||||
internalcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(*cfgPath, cfg)
|
||||
kubeadmutil.CheckErr(err)
|
||||
|
||||
// Execute the cmdFunc
|
||||
err = cmdFunc(internalcfg)
|
||||
kubeadmutil.CheckErr(err)
|
||||
}
|
||||
}
|
||||
240
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/certs_test.go
generated
vendored
Normal file
240
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/certs_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,240 @@
|
|||
/*
|
||||
Copyright 2017 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 phases
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
// required for triggering api machinery startup when running unit tests
|
||||
_ "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/install"
|
||||
|
||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/phases/certs/pkiutil"
|
||||
"k8s.io/kubernetes/pkg/util/node"
|
||||
|
||||
testutil "k8s.io/kubernetes/cmd/kubeadm/test"
|
||||
cmdtestutil "k8s.io/kubernetes/cmd/kubeadm/test/cmd"
|
||||
)
|
||||
|
||||
// phaseTestK8sVersion is a fake kubernetes version to use when testing
|
||||
const phaseTestK8sVersion = "v1.8.0"
|
||||
|
||||
func TestCertsSubCommandsHasFlags(t *testing.T) {
|
||||
|
||||
subCmds := getCertsSubCommands(phaseTestK8sVersion)
|
||||
|
||||
commonFlags := []string{
|
||||
"cert-dir",
|
||||
"config",
|
||||
}
|
||||
|
||||
var tests = []struct {
|
||||
command string
|
||||
additionalFlags []string
|
||||
}{
|
||||
{
|
||||
command: "all",
|
||||
additionalFlags: []string{
|
||||
"apiserver-advertise-address",
|
||||
"apiserver-cert-extra-sans",
|
||||
"service-cidr",
|
||||
"service-dns-domain",
|
||||
},
|
||||
},
|
||||
{
|
||||
command: "ca",
|
||||
},
|
||||
{
|
||||
command: "apiserver",
|
||||
additionalFlags: []string{
|
||||
"apiserver-advertise-address",
|
||||
"apiserver-cert-extra-sans",
|
||||
"service-cidr",
|
||||
"service-dns-domain",
|
||||
},
|
||||
},
|
||||
{
|
||||
command: "apiserver-kubelet-client",
|
||||
},
|
||||
{
|
||||
command: "sa",
|
||||
},
|
||||
{
|
||||
command: "front-proxy-ca",
|
||||
},
|
||||
{
|
||||
command: "front-proxy-client",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
expectedFlags := append(commonFlags, test.additionalFlags...)
|
||||
cmdtestutil.AssertSubCommandHasFlags(t, subCmds, test.command, expectedFlags...)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSubCmdCertsCreateFilesWithFlags(t *testing.T) {
|
||||
|
||||
subCmds := getCertsSubCommands(phaseTestK8sVersion)
|
||||
|
||||
var tests = []struct {
|
||||
subCmds []string
|
||||
expectedFiles []string
|
||||
}{
|
||||
{
|
||||
subCmds: []string{"all"},
|
||||
expectedFiles: []string{
|
||||
kubeadmconstants.CACertName, kubeadmconstants.CAKeyName,
|
||||
kubeadmconstants.APIServerCertName, kubeadmconstants.APIServerKeyName,
|
||||
kubeadmconstants.APIServerKubeletClientCertName, kubeadmconstants.APIServerKubeletClientKeyName,
|
||||
kubeadmconstants.ServiceAccountPrivateKeyName, kubeadmconstants.ServiceAccountPublicKeyName,
|
||||
kubeadmconstants.FrontProxyCACertName, kubeadmconstants.FrontProxyCAKeyName,
|
||||
kubeadmconstants.FrontProxyClientCertName, kubeadmconstants.FrontProxyClientKeyName,
|
||||
},
|
||||
},
|
||||
{
|
||||
subCmds: []string{"ca", "apiserver", "apiserver-kubelet-client"},
|
||||
expectedFiles: []string{kubeadmconstants.CACertName, kubeadmconstants.CAKeyName, kubeadmconstants.APIServerCertName, kubeadmconstants.APIServerKeyName, kubeadmconstants.APIServerKubeletClientCertName, kubeadmconstants.APIServerKubeletClientKeyName},
|
||||
},
|
||||
{
|
||||
subCmds: []string{"sa"},
|
||||
expectedFiles: []string{kubeadmconstants.ServiceAccountPrivateKeyName, kubeadmconstants.ServiceAccountPublicKeyName},
|
||||
},
|
||||
{
|
||||
subCmds: []string{"front-proxy-ca", "front-proxy-client"},
|
||||
expectedFiles: []string{kubeadmconstants.FrontProxyCACertName, kubeadmconstants.FrontProxyCAKeyName, kubeadmconstants.FrontProxyClientCertName, kubeadmconstants.FrontProxyClientKeyName},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
// Create temp folder for the test case
|
||||
tmpdir := testutil.SetupTempDir(t)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
|
||||
// executes given sub commands
|
||||
for _, subCmdName := range test.subCmds {
|
||||
certDirFlag := fmt.Sprintf("--cert-dir=%s", tmpdir)
|
||||
cmdtestutil.RunSubCommand(t, subCmds, subCmdName, certDirFlag)
|
||||
}
|
||||
|
||||
// verify expected files are there
|
||||
testutil.AssertFileExists(t, tmpdir, test.expectedFiles...)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSubCmdCertsApiServerForwardsFlags(t *testing.T) {
|
||||
|
||||
subCmds := getCertsSubCommands(phaseTestK8sVersion)
|
||||
|
||||
// Create temp folder for the test case
|
||||
tmpdir := testutil.SetupTempDir(t)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
|
||||
// creates ca cert
|
||||
certDirFlag := fmt.Sprintf("--cert-dir=%s", tmpdir)
|
||||
cmdtestutil.RunSubCommand(t, subCmds, "ca", certDirFlag)
|
||||
|
||||
// creates apiserver cert
|
||||
apiserverFlags := []string{
|
||||
fmt.Sprintf("--cert-dir=%s", tmpdir),
|
||||
"--apiserver-cert-extra-sans=foo,boo",
|
||||
"--service-cidr=10.0.0.0/24",
|
||||
"--service-dns-domain=mycluster.local",
|
||||
"--apiserver-advertise-address=1.2.3.4",
|
||||
}
|
||||
cmdtestutil.RunSubCommand(t, subCmds, "apiserver", apiserverFlags...)
|
||||
|
||||
// asserts created cert has values from CLI flags
|
||||
APIserverCert, err := pkiutil.TryLoadCertFromDisk(tmpdir, kubeadmconstants.APIServerCertAndKeyBaseName)
|
||||
if err != nil {
|
||||
t.Fatalf("Error loading API server certificate: %v", err)
|
||||
}
|
||||
|
||||
hostname := node.GetHostname("")
|
||||
|
||||
for i, name := range []string{hostname, "kubernetes", "kubernetes.default", "kubernetes.default.svc", "kubernetes.default.svc.mycluster.local"} {
|
||||
if APIserverCert.DNSNames[i] != name {
|
||||
t.Errorf("APIserverCert.DNSNames[%d] is %s instead of %s", i, APIserverCert.DNSNames[i], name)
|
||||
}
|
||||
}
|
||||
for i, ip := range []string{"10.0.0.1", "1.2.3.4"} {
|
||||
if APIserverCert.IPAddresses[i].String() != ip {
|
||||
t.Errorf("APIserverCert.IPAddresses[%d] is %s instead of %s", i, APIserverCert.IPAddresses[i], ip)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSubCmdCertsCreateFilesWithConfigFile(t *testing.T) {
|
||||
|
||||
subCmds := getCertsSubCommands(phaseTestK8sVersion)
|
||||
|
||||
var tests = []struct {
|
||||
subCmds []string
|
||||
expectedFiles []string
|
||||
}{
|
||||
{
|
||||
subCmds: []string{"all"},
|
||||
expectedFiles: []string{
|
||||
kubeadmconstants.CACertName, kubeadmconstants.CAKeyName,
|
||||
kubeadmconstants.APIServerCertName, kubeadmconstants.APIServerKeyName,
|
||||
kubeadmconstants.APIServerKubeletClientCertName, kubeadmconstants.APIServerKubeletClientKeyName,
|
||||
kubeadmconstants.ServiceAccountPrivateKeyName, kubeadmconstants.ServiceAccountPublicKeyName,
|
||||
kubeadmconstants.FrontProxyCACertName, kubeadmconstants.FrontProxyCAKeyName,
|
||||
kubeadmconstants.FrontProxyClientCertName, kubeadmconstants.FrontProxyClientKeyName,
|
||||
},
|
||||
},
|
||||
{
|
||||
subCmds: []string{"ca", "apiserver", "apiserver-kubelet-client"},
|
||||
expectedFiles: []string{kubeadmconstants.CACertName, kubeadmconstants.CAKeyName, kubeadmconstants.APIServerCertName, kubeadmconstants.APIServerKeyName, kubeadmconstants.APIServerKubeletClientCertName, kubeadmconstants.APIServerKubeletClientKeyName},
|
||||
},
|
||||
{
|
||||
subCmds: []string{"front-proxy-ca", "front-proxy-client"},
|
||||
expectedFiles: []string{kubeadmconstants.FrontProxyCACertName, kubeadmconstants.FrontProxyCAKeyName, kubeadmconstants.FrontProxyClientCertName, kubeadmconstants.FrontProxyClientKeyName},
|
||||
},
|
||||
{
|
||||
subCmds: []string{"sa"},
|
||||
expectedFiles: []string{kubeadmconstants.ServiceAccountPrivateKeyName, kubeadmconstants.ServiceAccountPublicKeyName},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
// Create temp folder for the test case
|
||||
tmpdir := testutil.SetupTempDir(t)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
|
||||
certdir := tmpdir
|
||||
|
||||
cfg := &kubeadmapi.MasterConfiguration{
|
||||
API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", BindPort: 1234},
|
||||
CertificatesDir: certdir,
|
||||
NodeName: "valid-node-name",
|
||||
}
|
||||
configPath := testutil.SetupMasterConfigurationFile(t, tmpdir, cfg)
|
||||
|
||||
// executes given sub commands
|
||||
for _, subCmdName := range test.subCmds {
|
||||
configFlag := fmt.Sprintf("--config=%s", configPath)
|
||||
cmdtestutil.RunSubCommand(t, subCmds, subCmdName, configFlag)
|
||||
}
|
||||
|
||||
// verify expected files are there
|
||||
testutil.AssertFileExists(t, tmpdir, test.expectedFiles...)
|
||||
}
|
||||
}
|
||||
116
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/controlplane.go
generated
vendored
Normal file
116
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/controlplane.go
generated
vendored
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
Copyright 2017 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 phases
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
kubeadmapiext "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1"
|
||||
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
|
||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
controlplanephase "k8s.io/kubernetes/cmd/kubeadm/app/phases/controlplane"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
)
|
||||
|
||||
// NewCmdControlplane return main command for Controlplane phase
|
||||
func NewCmdControlplane() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "controlplane",
|
||||
Short: "Generate all static pod manifest files necessary to establish the control plane.",
|
||||
RunE: cmdutil.SubCmdRunE("controlplane"),
|
||||
}
|
||||
|
||||
manifestPath := kubeadmconstants.GetStaticPodDirectory()
|
||||
cmd.AddCommand(getControlPlaneSubCommands(manifestPath, "")...)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// getControlPlaneSubCommands returns sub commands for Controlplane phase
|
||||
func getControlPlaneSubCommands(outDir, defaultKubernetesVersion string) []*cobra.Command {
|
||||
|
||||
cfg := &kubeadmapiext.MasterConfiguration{}
|
||||
|
||||
// This is used for unit testing only...
|
||||
// If we wouldn't set this to something, the code would dynamically look up the version from the internet
|
||||
// By setting this explicitely for tests workarounds that
|
||||
if defaultKubernetesVersion != "" {
|
||||
cfg.KubernetesVersion = defaultKubernetesVersion
|
||||
}
|
||||
|
||||
// Default values for the cobra help text
|
||||
api.Scheme.Default(cfg)
|
||||
|
||||
var cfgPath string
|
||||
var subCmds []*cobra.Command
|
||||
|
||||
subCmdProperties := []struct {
|
||||
use string
|
||||
short string
|
||||
cmdFunc func(outDir string, cfg *kubeadmapi.MasterConfiguration) error
|
||||
}{
|
||||
{
|
||||
use: "all",
|
||||
short: "Generate all static pod manifest files necessary to establish the control plane.",
|
||||
cmdFunc: controlplanephase.CreateInitStaticPodManifestFiles,
|
||||
},
|
||||
{
|
||||
use: "apiserver",
|
||||
short: "Generate apiserver static pod manifest.",
|
||||
cmdFunc: controlplanephase.CreateAPIServerStaticPodManifestFile,
|
||||
},
|
||||
{
|
||||
use: "controller-manager",
|
||||
short: "Generate controller-manager static pod manifest.",
|
||||
cmdFunc: controlplanephase.CreateControllerManagerStaticPodManifestFile,
|
||||
},
|
||||
{
|
||||
use: "scheduler",
|
||||
short: "Generate scheduler static pod manifest.",
|
||||
cmdFunc: controlplanephase.CreateSchedulerStaticPodManifestFile,
|
||||
},
|
||||
}
|
||||
|
||||
for _, properties := range subCmdProperties {
|
||||
// Creates the UX Command
|
||||
cmd := &cobra.Command{
|
||||
Use: properties.use,
|
||||
Short: properties.short,
|
||||
Run: runCmdPhase(properties.cmdFunc, &outDir, &cfgPath, cfg),
|
||||
}
|
||||
|
||||
// Add flags to the command
|
||||
cmd.Flags().StringVar(&cfg.CertificatesDir, "cert-dir", cfg.CertificatesDir, `The path where certificates are stored.`)
|
||||
cmd.Flags().StringVar(&cfg.KubernetesVersion, "kubernetes-version", cfg.KubernetesVersion, `Choose a specific Kubernetes version for the control plane.`)
|
||||
|
||||
if properties.use == "all" || properties.use == "apiserver" {
|
||||
cmd.Flags().StringVar(&cfg.API.AdvertiseAddress, "apiserver-advertise-address", cfg.API.AdvertiseAddress, "The IP address or DNS name the API Server is accessible on.")
|
||||
cmd.Flags().Int32Var(&cfg.API.BindPort, "apiserver-bind-port", cfg.API.BindPort, "The port the API Server is accessible on.")
|
||||
cmd.Flags().StringVar(&cfg.Networking.ServiceSubnet, "service-cidr", cfg.Networking.ServiceSubnet, "The range of IP address used for service VIPs.")
|
||||
}
|
||||
|
||||
if properties.use == "all" || properties.use == "controller-manager" {
|
||||
cmd.Flags().StringVar(&cfg.Networking.PodSubnet, "pod-network-cidr", cfg.Networking.PodSubnet, "The range of IP addresses used for the pod network.")
|
||||
}
|
||||
|
||||
cmd.Flags().StringVar(&cfgPath, "config", cfgPath, "Path to kubeadm config file (WARNING: Usage of a configuration file is experimental)")
|
||||
|
||||
subCmds = append(subCmds, cmd)
|
||||
}
|
||||
|
||||
return subCmds
|
||||
}
|
||||
150
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/controlplane_test.go
generated
vendored
Normal file
150
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/controlplane_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
Copyright 2017 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 phases
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
// required for triggering api machinery startup when running unit tests
|
||||
_ "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/install"
|
||||
|
||||
testutil "k8s.io/kubernetes/cmd/kubeadm/test"
|
||||
cmdtestutil "k8s.io/kubernetes/cmd/kubeadm/test/cmd"
|
||||
)
|
||||
|
||||
func TestControlPlaneSubCommandsHasFlags(t *testing.T) {
|
||||
|
||||
subCmds := getControlPlaneSubCommands("", phaseTestK8sVersion)
|
||||
|
||||
commonFlags := []string{
|
||||
"cert-dir",
|
||||
"config",
|
||||
}
|
||||
|
||||
var tests = []struct {
|
||||
command string
|
||||
additionalFlags []string
|
||||
}{
|
||||
{
|
||||
command: "all",
|
||||
additionalFlags: []string{
|
||||
"kubernetes-version",
|
||||
"apiserver-advertise-address",
|
||||
"apiserver-bind-port",
|
||||
"service-cidr",
|
||||
"pod-network-cidr",
|
||||
},
|
||||
},
|
||||
{
|
||||
command: "apiserver",
|
||||
additionalFlags: []string{
|
||||
"kubernetes-version",
|
||||
"apiserver-advertise-address",
|
||||
"apiserver-bind-port",
|
||||
"service-cidr",
|
||||
},
|
||||
},
|
||||
{
|
||||
command: "controller-manager",
|
||||
additionalFlags: []string{
|
||||
"kubernetes-version",
|
||||
"pod-network-cidr",
|
||||
},
|
||||
},
|
||||
{
|
||||
command: "scheduler",
|
||||
additionalFlags: []string{
|
||||
"kubernetes-version",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
expectedFlags := append(commonFlags, test.additionalFlags...)
|
||||
cmdtestutil.AssertSubCommandHasFlags(t, subCmds, test.command, expectedFlags...)
|
||||
}
|
||||
}
|
||||
|
||||
func TestControlPlaneCreateFilesWithFlags(t *testing.T) {
|
||||
|
||||
var tests = []struct {
|
||||
command string
|
||||
additionalFlags []string
|
||||
expectedFiles []string
|
||||
}{
|
||||
{
|
||||
command: "all",
|
||||
additionalFlags: []string{
|
||||
"--kubernetes-version=v1.7.0",
|
||||
"--apiserver-advertise-address=1.2.3.4",
|
||||
"--apiserver-bind-port=6443",
|
||||
"--service-cidr=1.2.3.4/16",
|
||||
"--pod-network-cidr=1.2.3.4/16",
|
||||
},
|
||||
expectedFiles: []string{
|
||||
"kube-apiserver.yaml",
|
||||
"kube-controller-manager.yaml",
|
||||
"kube-scheduler.yaml",
|
||||
},
|
||||
},
|
||||
{
|
||||
command: "apiserver",
|
||||
additionalFlags: []string{
|
||||
"--kubernetes-version=v1.7.0",
|
||||
"--apiserver-advertise-address=1.2.3.4",
|
||||
"--apiserver-bind-port=6443",
|
||||
"--service-cidr=1.2.3.4/16",
|
||||
},
|
||||
expectedFiles: []string{"kube-apiserver.yaml"},
|
||||
},
|
||||
{
|
||||
command: "controller-manager",
|
||||
additionalFlags: []string{
|
||||
"--kubernetes-version=v1.7.0",
|
||||
"--pod-network-cidr=1.2.3.4/16",
|
||||
},
|
||||
expectedFiles: []string{"kube-controller-manager.yaml"},
|
||||
},
|
||||
{
|
||||
command: "scheduler",
|
||||
additionalFlags: []string{
|
||||
"--kubernetes-version=v1.7.0",
|
||||
},
|
||||
expectedFiles: []string{"kube-scheduler.yaml"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
||||
// Create temp folder for the test case
|
||||
tmpdir := testutil.SetupTempDir(t)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
|
||||
// Get subcommands working in the temporary directory
|
||||
subCmds := getControlPlaneSubCommands(tmpdir, phaseTestK8sVersion)
|
||||
|
||||
// Execute the subcommand
|
||||
certDirFlag := fmt.Sprintf("--cert-dir=%s", tmpdir)
|
||||
allFlags := append(test.additionalFlags, certDirFlag)
|
||||
cmdtestutil.RunSubCommand(t, subCmds, test.command, allFlags...)
|
||||
|
||||
// Checks that requested files are there
|
||||
testutil.AssertFileExists(t, tmpdir, test.expectedFiles...)
|
||||
}
|
||||
}
|
||||
85
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/etcd.go
generated
vendored
Normal file
85
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/etcd.go
generated
vendored
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
Copyright 2017 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 phases
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
kubeadmapiext "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1"
|
||||
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
|
||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
etcdphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/etcd"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
)
|
||||
|
||||
// NewCmdEtcd return main command for Etcd phase
|
||||
func NewCmdEtcd() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "etcd",
|
||||
Short: "Generate static pod manifest file for etcd.",
|
||||
RunE: cmdutil.SubCmdRunE("etcd"),
|
||||
}
|
||||
|
||||
manifestPath := kubeadmconstants.GetStaticPodDirectory()
|
||||
cmd.AddCommand(getEtcdSubCommands(manifestPath, "")...)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// getEtcdSubCommands returns sub commands for etcd phase
|
||||
func getEtcdSubCommands(outDir, defaultKubernetesVersion string) []*cobra.Command {
|
||||
|
||||
cfg := &kubeadmapiext.MasterConfiguration{}
|
||||
|
||||
// This is used for unit testing only...
|
||||
// If we wouldn't set this to something, the code would dynamically look up the version from the internet
|
||||
// By setting this explicitely for tests workarounds that
|
||||
if defaultKubernetesVersion != "" {
|
||||
cfg.KubernetesVersion = defaultKubernetesVersion
|
||||
}
|
||||
|
||||
// Default values for the cobra help text
|
||||
api.Scheme.Default(cfg)
|
||||
|
||||
var cfgPath string
|
||||
var subCmds []*cobra.Command
|
||||
|
||||
properties := struct {
|
||||
use string
|
||||
short string
|
||||
cmdFunc func(outDir string, cfg *kubeadmapi.MasterConfiguration) error
|
||||
}{
|
||||
use: "local",
|
||||
short: "Generate static pod manifest file for a local, single-node etcd instance.",
|
||||
cmdFunc: etcdphase.CreateLocalEtcdStaticPodManifestFile,
|
||||
}
|
||||
|
||||
// Creates the UX Command
|
||||
cmd := &cobra.Command{
|
||||
Use: properties.use,
|
||||
Short: properties.short,
|
||||
Run: runCmdPhase(properties.cmdFunc, &outDir, &cfgPath, cfg),
|
||||
}
|
||||
|
||||
// Add flags to the command
|
||||
cmd.Flags().StringVar(&cfg.CertificatesDir, "cert-dir", cfg.CertificatesDir, `The path where certificates are stored`)
|
||||
cmd.Flags().StringVar(&cfgPath, "config", cfgPath, "Path to kubeadm config file (WARNING: Usage of a configuration file is experimental)")
|
||||
|
||||
subCmds = append(subCmds, cmd)
|
||||
|
||||
return subCmds
|
||||
}
|
||||
86
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/etcd_test.go
generated
vendored
Normal file
86
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/etcd_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
Copyright 2017 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 phases
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
// required for triggering api machinery startup when running unit tests
|
||||
_ "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/install"
|
||||
|
||||
testutil "k8s.io/kubernetes/cmd/kubeadm/test"
|
||||
cmdtestutil "k8s.io/kubernetes/cmd/kubeadm/test/cmd"
|
||||
)
|
||||
|
||||
func TestEtcdSubCommandsHasFlags(t *testing.T) {
|
||||
|
||||
subCmds := getEtcdSubCommands("", phaseTestK8sVersion)
|
||||
|
||||
commonFlags := []string{
|
||||
"cert-dir",
|
||||
"config",
|
||||
}
|
||||
|
||||
var tests = []struct {
|
||||
command string
|
||||
additionalFlags []string
|
||||
}{
|
||||
{
|
||||
command: "local",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
expectedFlags := append(commonFlags, test.additionalFlags...)
|
||||
cmdtestutil.AssertSubCommandHasFlags(t, subCmds, test.command, expectedFlags...)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEtcdCreateFilesWithFlags(t *testing.T) {
|
||||
|
||||
var tests = []struct {
|
||||
command string
|
||||
additionalFlags []string
|
||||
expectedFiles []string
|
||||
}{
|
||||
{
|
||||
command: "local",
|
||||
expectedFiles: []string{"etcd.yaml"},
|
||||
additionalFlags: []string{},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
||||
// Create temp folder for the test case
|
||||
tmpdir := testutil.SetupTempDir(t)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
|
||||
// Get subcommands working in the temporary directory
|
||||
subCmds := getEtcdSubCommands(tmpdir, phaseTestK8sVersion)
|
||||
|
||||
// Execute the subcommand
|
||||
certDirFlag := fmt.Sprintf("--cert-dir=%s", tmpdir)
|
||||
allFlags := append(test.additionalFlags, certDirFlag)
|
||||
cmdtestutil.RunSubCommand(t, subCmds, test.command, allFlags...)
|
||||
|
||||
// Checks that requested files are there
|
||||
testutil.AssertFileExists(t, tmpdir, test.expectedFiles...)
|
||||
}
|
||||
}
|
||||
139
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/kubeconfig.go
generated
vendored
Normal file
139
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/kubeconfig.go
generated
vendored
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
Copyright 2017 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 phases
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
kubeadmapiext "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1"
|
||||
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
|
||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
kubeconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
)
|
||||
|
||||
// NewCmdKubeConfig return main command for kubeconfig phase
|
||||
func NewCmdKubeConfig(out io.Writer) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "kubeconfig",
|
||||
Short: "Generate all kubeconfig files necessary to establish the control plane and the admin kubeconfig file.",
|
||||
RunE: cmdutil.SubCmdRunE("kubeconfig"),
|
||||
}
|
||||
|
||||
cmd.AddCommand(getKubeConfigSubCommands(out, kubeadmconstants.KubernetesDir, "")...)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// getKubeConfigSubCommands returns sub commands for kubeconfig phase
|
||||
func getKubeConfigSubCommands(out io.Writer, outDir, defaultKubernetesVersion string) []*cobra.Command {
|
||||
|
||||
cfg := &kubeadmapiext.MasterConfiguration{}
|
||||
|
||||
// This is used for unit testing only...
|
||||
// If we wouldn't set this to something, the code would dynamically look up the version from the internet
|
||||
// By setting this explicitely for tests workarounds that
|
||||
if defaultKubernetesVersion != "" {
|
||||
cfg.KubernetesVersion = defaultKubernetesVersion
|
||||
}
|
||||
|
||||
// Default values for the cobra help text
|
||||
api.Scheme.Default(cfg)
|
||||
|
||||
var cfgPath, token, clientName string
|
||||
var subCmds []*cobra.Command
|
||||
|
||||
subCmdProperties := []struct {
|
||||
use string
|
||||
short string
|
||||
cmdFunc func(outDir string, cfg *kubeadmapi.MasterConfiguration) error
|
||||
}{
|
||||
{
|
||||
use: "all",
|
||||
short: "Generate all kubeconfig files necessary to establish the control plane and the admin kubeconfig file.",
|
||||
cmdFunc: kubeconfigphase.CreateInitKubeConfigFiles,
|
||||
},
|
||||
{
|
||||
use: "admin",
|
||||
short: "Generate a kubeconfig file for the admin to use and for kubeadm itself.",
|
||||
cmdFunc: kubeconfigphase.CreateAdminKubeConfigFile,
|
||||
},
|
||||
{
|
||||
use: "kubelet",
|
||||
short: "Generate a kubeconfig file for the Kubelet to use. Please note that this should *only* be used for bootstrapping purposes. After your control plane is up, you should request all kubelet credentials from the CSR API.",
|
||||
cmdFunc: kubeconfigphase.CreateKubeletKubeConfigFile,
|
||||
},
|
||||
{
|
||||
use: "controller-manager",
|
||||
short: "Generate a kubeconfig file for the Controller Manager to use.",
|
||||
cmdFunc: kubeconfigphase.CreateControllerManagerKubeConfigFile,
|
||||
},
|
||||
{
|
||||
use: "scheduler",
|
||||
short: "Generate a kubeconfig file for the Scheduler to use.",
|
||||
cmdFunc: kubeconfigphase.CreateSchedulerKubeConfigFile,
|
||||
},
|
||||
{
|
||||
use: "user",
|
||||
short: "Outputs a kubeconfig file for an additional user.",
|
||||
cmdFunc: func(outDir string, cfg *kubeadmapi.MasterConfiguration) error {
|
||||
if clientName == "" {
|
||||
return fmt.Errorf("missing required argument client-name")
|
||||
}
|
||||
|
||||
// if the kubeconfig file for an additional user has to use a token, use it
|
||||
if token != "" {
|
||||
return kubeconfigphase.WriteKubeConfigWithToken(out, cfg, clientName, token)
|
||||
}
|
||||
|
||||
// Otherwise, write a kubeconfig file with a generate client cert
|
||||
return kubeconfigphase.WriteKubeConfigWithClientCert(out, cfg, clientName)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, properties := range subCmdProperties {
|
||||
// Creates the UX Command
|
||||
cmd := &cobra.Command{
|
||||
Use: properties.use,
|
||||
Short: properties.short,
|
||||
Run: runCmdPhase(properties.cmdFunc, &outDir, &cfgPath, cfg),
|
||||
}
|
||||
|
||||
// Add flags to the command
|
||||
if properties.use != "user" {
|
||||
cmd.Flags().StringVar(&cfgPath, "config", cfgPath, "Path to kubeadm config file (WARNING: Usage of a configuration file is experimental)")
|
||||
}
|
||||
cmd.Flags().StringVar(&cfg.CertificatesDir, "cert-dir", cfg.CertificatesDir, "The path where certificates are stored.")
|
||||
cmd.Flags().StringVar(&cfg.API.AdvertiseAddress, "apiserver-advertise-address", cfg.API.AdvertiseAddress, "The IP address or DNS name the API Server is accessible on.")
|
||||
cmd.Flags().Int32Var(&cfg.API.BindPort, "apiserver-bind-port", cfg.API.BindPort, "The port the API Server is accessible on.")
|
||||
if properties.use == "all" || properties.use == "kubelet" {
|
||||
cmd.Flags().StringVar(&cfg.NodeName, "node-name", cfg.NodeName, `The node name that the kubelet client cert should use.`)
|
||||
}
|
||||
if properties.use == "user" {
|
||||
cmd.Flags().StringVar(&token, "token", token, "The token that should be used as the authentication mechanism for this kubeconfig.")
|
||||
cmd.Flags().StringVar(&clientName, "client-name", clientName, "The name of the KubeConfig user that will be created. Will also be used as the CN if client certs are created.")
|
||||
}
|
||||
|
||||
subCmds = append(subCmds, cmd)
|
||||
}
|
||||
|
||||
return subCmds
|
||||
}
|
||||
383
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/kubeconfig_test.go
generated
vendored
Normal file
383
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/kubeconfig_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,383 @@
|
|||
/*
|
||||
Copyright 2017 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 phases
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
// required for triggering api machinery startup when running unit tests
|
||||
_ "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/install"
|
||||
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/phases/certs/pkiutil"
|
||||
|
||||
testutil "k8s.io/kubernetes/cmd/kubeadm/test"
|
||||
cmdtestutil "k8s.io/kubernetes/cmd/kubeadm/test/cmd"
|
||||
kubeconfigtestutil "k8s.io/kubernetes/cmd/kubeadm/test/kubeconfig"
|
||||
)
|
||||
|
||||
func TestKubeConfigCSubCommandsHasFlags(t *testing.T) {
|
||||
|
||||
subCmds := getKubeConfigSubCommands(nil, "", phaseTestK8sVersion)
|
||||
|
||||
commonFlags := []string{
|
||||
"cert-dir",
|
||||
"apiserver-advertise-address",
|
||||
"apiserver-bind-port",
|
||||
}
|
||||
|
||||
var tests = []struct {
|
||||
command string
|
||||
additionalFlags []string
|
||||
}{
|
||||
{
|
||||
command: "all",
|
||||
additionalFlags: []string{
|
||||
"config",
|
||||
"node-name",
|
||||
},
|
||||
},
|
||||
{
|
||||
command: "admin",
|
||||
additionalFlags: []string{
|
||||
"config",
|
||||
},
|
||||
},
|
||||
{
|
||||
command: "kubelet",
|
||||
additionalFlags: []string{
|
||||
"config",
|
||||
"node-name",
|
||||
},
|
||||
},
|
||||
{
|
||||
command: "controller-manager",
|
||||
additionalFlags: []string{
|
||||
"config",
|
||||
},
|
||||
},
|
||||
{
|
||||
command: "scheduler",
|
||||
additionalFlags: []string{
|
||||
"config",
|
||||
},
|
||||
},
|
||||
{
|
||||
command: "user",
|
||||
additionalFlags: []string{
|
||||
"token",
|
||||
"client-name",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
expectedFlags := append(commonFlags, test.additionalFlags...)
|
||||
cmdtestutil.AssertSubCommandHasFlags(t, subCmds, test.command, expectedFlags...)
|
||||
}
|
||||
}
|
||||
|
||||
func TestKubeConfigSubCommandsThatCreateFilesWithFlags(t *testing.T) {
|
||||
|
||||
commonFlags := []string{
|
||||
"--apiserver-advertise-address=1.2.3.4",
|
||||
"--apiserver-bind-port=1234",
|
||||
}
|
||||
|
||||
var tests = []struct {
|
||||
command string
|
||||
additionalFlags []string
|
||||
expectedFiles []string
|
||||
}{
|
||||
{
|
||||
command: "all",
|
||||
additionalFlags: []string{"--node-name=valid-nome-name"},
|
||||
expectedFiles: []string{
|
||||
kubeadmconstants.AdminKubeConfigFileName,
|
||||
kubeadmconstants.KubeletKubeConfigFileName,
|
||||
kubeadmconstants.ControllerManagerKubeConfigFileName,
|
||||
kubeadmconstants.SchedulerKubeConfigFileName,
|
||||
},
|
||||
},
|
||||
{
|
||||
command: "admin",
|
||||
expectedFiles: []string{kubeadmconstants.AdminKubeConfigFileName},
|
||||
},
|
||||
{
|
||||
command: "kubelet",
|
||||
additionalFlags: []string{"--node-name=valid-nome-name"},
|
||||
expectedFiles: []string{kubeadmconstants.KubeletKubeConfigFileName},
|
||||
},
|
||||
{
|
||||
command: "controller-manager",
|
||||
expectedFiles: []string{kubeadmconstants.ControllerManagerKubeConfigFileName},
|
||||
},
|
||||
{
|
||||
command: "scheduler",
|
||||
expectedFiles: []string{kubeadmconstants.SchedulerKubeConfigFileName},
|
||||
},
|
||||
}
|
||||
|
||||
var kubeConfigAssertions = map[string]struct {
|
||||
clientName string
|
||||
organizations []string
|
||||
}{
|
||||
kubeadmconstants.AdminKubeConfigFileName: {
|
||||
clientName: "kubernetes-admin",
|
||||
organizations: []string{kubeadmconstants.MastersGroup},
|
||||
},
|
||||
kubeadmconstants.KubeletKubeConfigFileName: {
|
||||
clientName: "system:node:valid-nome-name",
|
||||
organizations: []string{kubeadmconstants.NodesGroup},
|
||||
},
|
||||
kubeadmconstants.ControllerManagerKubeConfigFileName: {
|
||||
clientName: kubeadmconstants.ControllerManagerUser,
|
||||
},
|
||||
kubeadmconstants.SchedulerKubeConfigFileName: {
|
||||
clientName: kubeadmconstants.SchedulerUser,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
||||
// Create temp folder for the test case
|
||||
tmpdir := testutil.SetupTempDir(t)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
|
||||
// Adds a pki folder with a ca certs to the temp folder
|
||||
pkidir := testutil.SetupPkiDirWithCertificateAuthorithy(t, tmpdir)
|
||||
|
||||
// Retrives ca cert for assertions
|
||||
caCert, _, err := pkiutil.TryLoadCertAndKeyFromDisk(pkidir, kubeadmconstants.CACertAndKeyBaseName)
|
||||
if err != nil {
|
||||
t.Fatalf("couldn't retrive ca cert: %v", err)
|
||||
}
|
||||
|
||||
// Get subcommands working in the temporary directory
|
||||
subCmds := getKubeConfigSubCommands(nil, tmpdir, phaseTestK8sVersion)
|
||||
|
||||
// Execute the subcommand
|
||||
certDirFlag := fmt.Sprintf("--cert-dir=%s", pkidir)
|
||||
allFlags := append(commonFlags, certDirFlag)
|
||||
allFlags = append(allFlags, test.additionalFlags...)
|
||||
cmdtestutil.RunSubCommand(t, subCmds, test.command, allFlags...)
|
||||
|
||||
// Checks that requested files are there
|
||||
testutil.AssertFileExists(t, tmpdir, test.expectedFiles...)
|
||||
|
||||
// Checks contents of generated files
|
||||
for _, file := range test.expectedFiles {
|
||||
|
||||
// reads generated files
|
||||
config, err := clientcmd.LoadFromFile(filepath.Join(tmpdir, file))
|
||||
if err != nil {
|
||||
t.Errorf("Couldn't load generated kubeconfig file: %v", err)
|
||||
}
|
||||
|
||||
// checks that CLI flags are properly propagated and kubeconfig properties are correct
|
||||
kubeconfigtestutil.AssertKubeConfigCurrentCluster(t, config, "https://1.2.3.4:1234", caCert)
|
||||
|
||||
expectedClientName := kubeConfigAssertions[file].clientName
|
||||
expectedOrganizations := kubeConfigAssertions[file].organizations
|
||||
kubeconfigtestutil.AssertKubeConfigCurrentAuthInfoWithClientCert(t, config, caCert, expectedClientName, expectedOrganizations...)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestKubeConfigSubCommandsThatCreateFilesWithConfigFile(t *testing.T) {
|
||||
|
||||
var tests = []struct {
|
||||
command string
|
||||
expectedFiles []string
|
||||
}{
|
||||
{
|
||||
command: "all",
|
||||
expectedFiles: []string{
|
||||
kubeadmconstants.AdminKubeConfigFileName,
|
||||
kubeadmconstants.KubeletKubeConfigFileName,
|
||||
kubeadmconstants.ControllerManagerKubeConfigFileName,
|
||||
kubeadmconstants.SchedulerKubeConfigFileName,
|
||||
},
|
||||
},
|
||||
{
|
||||
command: "admin",
|
||||
expectedFiles: []string{kubeadmconstants.AdminKubeConfigFileName},
|
||||
},
|
||||
{
|
||||
command: "kubelet",
|
||||
expectedFiles: []string{kubeadmconstants.KubeletKubeConfigFileName},
|
||||
},
|
||||
{
|
||||
command: "controller-manager",
|
||||
expectedFiles: []string{kubeadmconstants.ControllerManagerKubeConfigFileName},
|
||||
},
|
||||
{
|
||||
command: "scheduler",
|
||||
expectedFiles: []string{kubeadmconstants.SchedulerKubeConfigFileName},
|
||||
},
|
||||
}
|
||||
|
||||
var kubeConfigAssertions = map[string]struct {
|
||||
clientName string
|
||||
organizations []string
|
||||
}{
|
||||
kubeadmconstants.AdminKubeConfigFileName: {
|
||||
clientName: "kubernetes-admin",
|
||||
organizations: []string{kubeadmconstants.MastersGroup},
|
||||
},
|
||||
kubeadmconstants.KubeletKubeConfigFileName: {
|
||||
clientName: "system:node:valid-node-name",
|
||||
organizations: []string{kubeadmconstants.NodesGroup},
|
||||
},
|
||||
kubeadmconstants.ControllerManagerKubeConfigFileName: {
|
||||
clientName: kubeadmconstants.ControllerManagerUser,
|
||||
},
|
||||
kubeadmconstants.SchedulerKubeConfigFileName: {
|
||||
clientName: kubeadmconstants.SchedulerUser,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
||||
// Create temp folder for the test case
|
||||
tmpdir := testutil.SetupTempDir(t)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
|
||||
// Adds a pki folder with a ca certs to the temp folder
|
||||
pkidir := testutil.SetupPkiDirWithCertificateAuthorithy(t, tmpdir)
|
||||
|
||||
// Retrives ca cert for assertions
|
||||
caCert, _, err := pkiutil.TryLoadCertAndKeyFromDisk(pkidir, kubeadmconstants.CACertAndKeyBaseName)
|
||||
if err != nil {
|
||||
t.Fatalf("couldn't retrive ca cert: %v", err)
|
||||
}
|
||||
|
||||
// Adds a master configuration file
|
||||
cfg := &kubeadmapi.MasterConfiguration{
|
||||
API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", BindPort: 1234},
|
||||
CertificatesDir: pkidir,
|
||||
NodeName: "valid-node-name",
|
||||
}
|
||||
cfgPath := testutil.SetupMasterConfigurationFile(t, tmpdir, cfg)
|
||||
|
||||
// Get subcommands working in the temporary directory
|
||||
subCmds := getKubeConfigSubCommands(nil, tmpdir, phaseTestK8sVersion)
|
||||
|
||||
// Execute the subcommand
|
||||
configFlag := fmt.Sprintf("--config=%s", cfgPath)
|
||||
cmdtestutil.RunSubCommand(t, subCmds, test.command, configFlag)
|
||||
|
||||
// Checks that requested files are there
|
||||
testutil.AssertFileExists(t, tmpdir, test.expectedFiles...)
|
||||
|
||||
// Checks contents of generated files
|
||||
for _, file := range test.expectedFiles {
|
||||
|
||||
// reads generated files
|
||||
config, err := clientcmd.LoadFromFile(filepath.Join(tmpdir, file))
|
||||
if err != nil {
|
||||
t.Errorf("Couldn't load generated kubeconfig file: %v", err)
|
||||
}
|
||||
|
||||
// checks that config file properties are properly propagated and kubeconfig properties are correct
|
||||
kubeconfigtestutil.AssertKubeConfigCurrentCluster(t, config, "https://1.2.3.4:1234", caCert)
|
||||
|
||||
expectedClientName := kubeConfigAssertions[file].clientName
|
||||
expectedOrganizations := kubeConfigAssertions[file].organizations
|
||||
kubeconfigtestutil.AssertKubeConfigCurrentAuthInfoWithClientCert(t, config, caCert, expectedClientName, expectedOrganizations...)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestKubeConfigSubCommandsThatWritesToOut(t *testing.T) {
|
||||
|
||||
// Temporary folders for the test case
|
||||
tmpdir := testutil.SetupTempDir(t)
|
||||
defer os.RemoveAll(tmpdir)
|
||||
|
||||
// Adds a pki folder with a ca cert to the temp folder
|
||||
pkidir := testutil.SetupPkiDirWithCertificateAuthorithy(t, tmpdir)
|
||||
|
||||
// Retrives ca cert for assertions
|
||||
caCert, _, err := pkiutil.TryLoadCertAndKeyFromDisk(pkidir, kubeadmconstants.CACertAndKeyBaseName)
|
||||
if err != nil {
|
||||
t.Fatalf("couldn't retrive ca cert: %v", err)
|
||||
}
|
||||
|
||||
commonFlags := []string{
|
||||
"--apiserver-advertise-address=1.2.3.4",
|
||||
"--apiserver-bind-port=1234",
|
||||
"--client-name=myUser",
|
||||
fmt.Sprintf("--cert-dir=%s", pkidir),
|
||||
}
|
||||
|
||||
var tests = []struct {
|
||||
command string
|
||||
withClientCert bool
|
||||
withToken bool
|
||||
additionalFlags []string
|
||||
}{
|
||||
{ // Test user subCommand withClientCert
|
||||
command: "user",
|
||||
withClientCert: true,
|
||||
},
|
||||
{ // Test user subCommand withToken
|
||||
withToken: true,
|
||||
command: "user",
|
||||
additionalFlags: []string{"--token=123456"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
buf := new(bytes.Buffer)
|
||||
|
||||
// Get subcommands working in the temporary directory
|
||||
subCmds := getKubeConfigSubCommands(buf, tmpdir, phaseTestK8sVersion)
|
||||
|
||||
// Execute the subcommand
|
||||
allFlags := append(commonFlags, test.additionalFlags...)
|
||||
cmdtestutil.RunSubCommand(t, subCmds, test.command, allFlags...)
|
||||
|
||||
// reads kubeconfig written to stdout
|
||||
config, err := clientcmd.Load(buf.Bytes())
|
||||
if err != nil {
|
||||
t.Errorf("Couldn't read kubeconfig file from buffer: %v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
// checks that CLI flags are properly propagated
|
||||
kubeconfigtestutil.AssertKubeConfigCurrentCluster(t, config, "https://1.2.3.4:1234", caCert)
|
||||
|
||||
if test.withClientCert {
|
||||
// checks that kubeconfig files have expected client cert
|
||||
kubeconfigtestutil.AssertKubeConfigCurrentAuthInfoWithClientCert(t, config, caCert, "myUser")
|
||||
}
|
||||
|
||||
if test.withToken {
|
||||
// checks that kubeconfig files have expected token
|
||||
kubeconfigtestutil.AssertKubeConfigCurrentAuthInfoWithToken(t, config, "myUser", "123456")
|
||||
}
|
||||
}
|
||||
}
|
||||
49
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/markmaster.go
generated
vendored
Normal file
49
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/markmaster.go
generated
vendored
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
Copyright 2017 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 phases
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
|
||||
markmasterphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/markmaster"
|
||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
|
||||
)
|
||||
|
||||
// NewCmdMarkMaster returns the Cobra command for running the mark-master phase
|
||||
func NewCmdMarkMaster() *cobra.Command {
|
||||
var kubeConfigFile string
|
||||
cmd := &cobra.Command{
|
||||
Use: "mark-master <node-name>",
|
||||
Short: "Mark a node as master.",
|
||||
Aliases: []string{"markmaster"},
|
||||
RunE: func(_ *cobra.Command, args []string) error {
|
||||
err := cmdutil.ValidateExactArgNumber(args, []string{"node-name"})
|
||||
kubeadmutil.CheckErr(err)
|
||||
|
||||
client, err := kubeconfigutil.ClientSetFromFile(kubeConfigFile)
|
||||
kubeadmutil.CheckErr(err)
|
||||
|
||||
nodeName := args[0]
|
||||
return markmasterphase.MarkMaster(client, nodeName)
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().StringVar(&kubeConfigFile, "kubeconfig", "/etc/kubernetes/admin.conf", "The KubeConfig file to use for talking to the cluster")
|
||||
return cmd
|
||||
}
|
||||
46
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/phase.go
generated
vendored
Normal file
46
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/phase.go
generated
vendored
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
Copyright 2017 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 phases
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
|
||||
)
|
||||
|
||||
// NewCmdPhase returns the cobra command for the "kubeadm phase" command (currently alpha-gated)
|
||||
func NewCmdPhase(out io.Writer) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "phase",
|
||||
Short: "Invoke subsets of kubeadm functions separately for a manual install.",
|
||||
RunE: cmdutil.SubCmdRunE("phase"),
|
||||
}
|
||||
|
||||
cmd.AddCommand(NewCmdAddon())
|
||||
cmd.AddCommand(NewCmdBootstrapToken())
|
||||
cmd.AddCommand(NewCmdCerts())
|
||||
cmd.AddCommand(NewCmdControlplane())
|
||||
cmd.AddCommand(NewCmdEtcd())
|
||||
cmd.AddCommand(NewCmdKubeConfig(out))
|
||||
cmd.AddCommand(NewCmdMarkMaster())
|
||||
cmd.AddCommand(NewCmdPreFlight())
|
||||
cmd.AddCommand(NewCmdSelfhosting())
|
||||
cmd.AddCommand(NewCmdUploadConfig())
|
||||
|
||||
return cmd
|
||||
}
|
||||
63
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/preflight.go
generated
vendored
Normal file
63
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/preflight.go
generated
vendored
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
Copyright 2017 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 phases
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/preflight"
|
||||
)
|
||||
|
||||
func NewCmdPreFlight() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "preflight",
|
||||
Short: "Run pre-flight checks",
|
||||
RunE: cmdutil.SubCmdRunE("preflight"),
|
||||
}
|
||||
|
||||
cmd.AddCommand(NewCmdPreFlightMaster())
|
||||
cmd.AddCommand(NewCmdPreFlightNode())
|
||||
return cmd
|
||||
}
|
||||
|
||||
func NewCmdPreFlightMaster() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "master",
|
||||
Short: "Run master pre-flight checks",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
cfg := &kubeadmapi.MasterConfiguration{}
|
||||
return preflight.RunInitMasterChecks(cfg)
|
||||
},
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func NewCmdPreFlightNode() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "node",
|
||||
Short: "Run node pre-flight checks",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
cfg := &kubeadmapi.NodeConfiguration{}
|
||||
return preflight.RunJoinNodeChecks(cfg)
|
||||
},
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
103
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/selfhosting.go
generated
vendored
Normal file
103
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/selfhosting.go
generated
vendored
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
Copyright 2017 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 phases
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
kubeadmapiext "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation"
|
||||
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/features"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/phases/selfhosting"
|
||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient"
|
||||
configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config"
|
||||
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
)
|
||||
|
||||
// NewCmdSelfhosting returns the self-hosting Cobra command
|
||||
func NewCmdSelfhosting() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "selfhosting",
|
||||
Aliases: []string{"selfhosted"},
|
||||
Short: "Make a kubeadm cluster self-hosted.",
|
||||
RunE: cmdutil.SubCmdRunE("selfhosting"),
|
||||
}
|
||||
|
||||
cmd.AddCommand(getSelfhostingSubCommand())
|
||||
return cmd
|
||||
}
|
||||
|
||||
// getSelfhostingSubCommand returns sub commands for Selfhosting phase
|
||||
func getSelfhostingSubCommand() *cobra.Command {
|
||||
|
||||
cfg := &kubeadmapiext.MasterConfiguration{}
|
||||
// Default values for the cobra help text
|
||||
api.Scheme.Default(cfg)
|
||||
|
||||
var cfgPath, kubeConfigFile, featureGatesString string
|
||||
|
||||
// Creates the UX Command
|
||||
cmd := &cobra.Command{
|
||||
Use: "convert-from-staticpods",
|
||||
Aliases: []string{"from-staticpods"},
|
||||
Short: "Converts a Static Pod-hosted control plane into a self-hosted one.",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
var err error
|
||||
if cfg.FeatureGates, err = features.NewFeatureGate(&features.InitFeatureGates, featureGatesString); err != nil {
|
||||
kubeadmutil.CheckErr(err)
|
||||
}
|
||||
|
||||
if err := validation.ValidateMixedArguments(cmd.Flags()); err != nil {
|
||||
kubeadmutil.CheckErr(err)
|
||||
}
|
||||
|
||||
// This call returns the ready-to-use configuration based on the configuration file that might or might not exist and the default cfg populated by flags
|
||||
internalcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(cfgPath, cfg)
|
||||
kubeadmutil.CheckErr(err)
|
||||
|
||||
// Gets the kubernetes client
|
||||
client, err := kubeconfigutil.ClientSetFromFile(kubeConfigFile)
|
||||
kubeadmutil.CheckErr(err)
|
||||
|
||||
// Converts the Static Pod-hosted control plane into a self-hosted one
|
||||
waiter := apiclient.NewKubeWaiter(client, 2*time.Minute, os.Stdout)
|
||||
err = selfhosting.CreateSelfHostedControlPlane(constants.GetStaticPodDirectory(), constants.KubernetesDir, internalcfg, client, waiter)
|
||||
kubeadmutil.CheckErr(err)
|
||||
},
|
||||
}
|
||||
|
||||
// Add flags to the command
|
||||
// flags bound to the configuration object
|
||||
cmd.Flags().StringVar(&cfg.CertificatesDir, "cert-dir", cfg.CertificatesDir, `The path where certificates are stored`)
|
||||
cmd.Flags().StringVar(&cfgPath, "config", cfgPath, "Path to kubeadm config file (WARNING: Usage of a configuration file is experimental)")
|
||||
cmd.Flags().StringVar(&featureGatesString, "feature-gates", featureGatesString, "A set of key=value pairs that describe feature gates for various features."+
|
||||
"Options are:\n"+strings.Join(features.KnownFeatures(&features.InitFeatureGates), "\n"))
|
||||
|
||||
// flags that are not bound to the configuration object
|
||||
// Note: All flags that are not bound to the cfg object should be whitelisted in cmd/kubeadm/app/apis/kubeadm/validation/validation.go
|
||||
cmd.Flags().StringVar(&kubeConfigFile, "kubeconfig", "/etc/kubernetes/admin.conf", "The KubeConfig file to use for talking to the cluster")
|
||||
|
||||
return cmd
|
||||
}
|
||||
58
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/uploadconfig.go
generated
vendored
Normal file
58
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/uploadconfig.go
generated
vendored
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
Copyright 2017 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 phases
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
kubeadmapiext "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/phases/uploadconfig"
|
||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||
configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config"
|
||||
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
|
||||
)
|
||||
|
||||
// NewCmdUploadConfig returns the Cobra command for running the uploadconfig phase
|
||||
func NewCmdUploadConfig() *cobra.Command {
|
||||
var cfgPath, kubeConfigFile string
|
||||
cmd := &cobra.Command{
|
||||
Use: "upload-config",
|
||||
Short: "Upload the currently used configuration for kubeadm to a ConfigMap in the cluster for future use in reconfiguration and upgrades of the cluster.",
|
||||
Aliases: []string{"uploadconfig"},
|
||||
Run: func(_ *cobra.Command, args []string) {
|
||||
if len(cfgPath) == 0 {
|
||||
kubeadmutil.CheckErr(fmt.Errorf("The --config flag is mandatory"))
|
||||
}
|
||||
client, err := kubeconfigutil.ClientSetFromFile(kubeConfigFile)
|
||||
kubeadmutil.CheckErr(err)
|
||||
|
||||
defaultcfg := &kubeadmapiext.MasterConfiguration{}
|
||||
internalcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(cfgPath, defaultcfg)
|
||||
kubeadmutil.CheckErr(err)
|
||||
|
||||
err = uploadconfig.UploadConfiguration(internalcfg, client)
|
||||
kubeadmutil.CheckErr(err)
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().StringVar(&kubeConfigFile, "kubeconfig", "/etc/kubernetes/admin.conf", "The KubeConfig file to use for talking to the cluster")
|
||||
cmd.Flags().StringVar(&cfgPath, "config", "", "Path to kubeadm config file (WARNING: Usage of a configuration file is experimental)")
|
||||
|
||||
return cmd
|
||||
}
|
||||
50
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/util.go
generated
vendored
Normal file
50
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/util.go
generated
vendored
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
Copyright 2017 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 phases
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
kubeadmapiext "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation"
|
||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||
configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config"
|
||||
)
|
||||
|
||||
// runCmdPhase creates a cobra.Command Run function, by composing the call to the given cmdFunc with necessary additional steps (e.g preparation of input parameters)
|
||||
func runCmdPhase(cmdFunc func(outDir string, cfg *kubeadmapi.MasterConfiguration) error, outDir, cfgPath *string, cfg *kubeadmapiext.MasterConfiguration) func(cmd *cobra.Command, args []string) {
|
||||
|
||||
// the following statement build a clousure that wraps a call to a cmdFunc, binding
|
||||
// the function itself with the specific parameters of each sub command.
|
||||
// Please note that specific parameter should be passed as value, while other parameters - passed as reference -
|
||||
// are shared between sub commands and gets access to current value e.g. flags value.
|
||||
|
||||
return func(cmd *cobra.Command, args []string) {
|
||||
if err := validation.ValidateMixedArguments(cmd.Flags()); err != nil {
|
||||
kubeadmutil.CheckErr(err)
|
||||
}
|
||||
|
||||
// This call returns the ready-to-use configuration based on the configuration file that might or might not exist and the default cfg populated by flags
|
||||
internalcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(*cfgPath, cfg)
|
||||
kubeadmutil.CheckErr(err)
|
||||
|
||||
// Execute the cmdFunc
|
||||
err = cmdFunc(*outDir, internalcfg)
|
||||
kubeadmutil.CheckErr(err)
|
||||
}
|
||||
}
|
||||
189
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/reset.go
generated
vendored
Normal file
189
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/reset.go
generated
vendored
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
/*
|
||||
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 cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
kubeadmapiext "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1"
|
||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/preflight"
|
||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||
"k8s.io/kubernetes/pkg/util/initsystem"
|
||||
)
|
||||
|
||||
// NewCmdReset returns the "kubeadm reset" command
|
||||
func NewCmdReset(out io.Writer) *cobra.Command {
|
||||
var skipPreFlight bool
|
||||
var certsDir string
|
||||
cmd := &cobra.Command{
|
||||
Use: "reset",
|
||||
Short: "Run this to revert any changes made to this host by 'kubeadm init' or 'kubeadm join'.",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
r, err := NewReset(skipPreFlight, certsDir)
|
||||
kubeadmutil.CheckErr(err)
|
||||
kubeadmutil.CheckErr(r.Run(out))
|
||||
},
|
||||
}
|
||||
|
||||
cmd.PersistentFlags().BoolVar(
|
||||
&skipPreFlight, "skip-preflight-checks", false,
|
||||
"Skip preflight checks normally run before modifying the system",
|
||||
)
|
||||
|
||||
cmd.PersistentFlags().StringVar(
|
||||
&certsDir, "cert-dir", kubeadmapiext.DefaultCertificatesDir,
|
||||
"The path to the directory where the certificates are stored. If specified, clean this directory.",
|
||||
)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
type Reset struct {
|
||||
certsDir string
|
||||
}
|
||||
|
||||
func NewReset(skipPreFlight bool, certsDir string) (*Reset, error) {
|
||||
if !skipPreFlight {
|
||||
fmt.Println("[preflight] Running pre-flight checks")
|
||||
|
||||
if err := preflight.RunRootCheckOnly(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
fmt.Println("[preflight] Skipping pre-flight checks")
|
||||
}
|
||||
|
||||
return &Reset{
|
||||
certsDir: certsDir,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Run reverts any changes made to this host by "kubeadm init" or "kubeadm join".
|
||||
func (r *Reset) Run(out io.Writer) error {
|
||||
|
||||
// Try to stop the kubelet service
|
||||
initSystem, err := initsystem.GetInitSystem()
|
||||
if err != nil {
|
||||
fmt.Println("[reset] WARNING: The kubelet service couldn't be stopped by kubeadm because no supported init system was detected.")
|
||||
fmt.Println("[reset] WARNING: Please ensure kubelet is stopped manually.")
|
||||
} else {
|
||||
fmt.Println("[reset] Stopping the kubelet service")
|
||||
if err := initSystem.ServiceStop("kubelet"); err != nil {
|
||||
fmt.Printf("[reset] WARNING: The kubelet service couldn't be stopped by kubeadm: [%v]\n", err)
|
||||
fmt.Println("[reset] WARNING: Please ensure kubelet is stopped manually.")
|
||||
}
|
||||
}
|
||||
|
||||
// Try to unmount mounted directories under /var/lib/kubelet in order to be able to remove the /var/lib/kubelet directory later
|
||||
fmt.Printf("[reset] Unmounting mounted directories in %q\n", "/var/lib/kubelet")
|
||||
umountDirsCmd := "awk '$2 ~ path {print $2}' path=/var/lib/kubelet /proc/mounts | xargs -r umount"
|
||||
umountOutputBytes, err := exec.Command("sh", "-c", umountDirsCmd).Output()
|
||||
if err != nil {
|
||||
fmt.Printf("[reset] Failed to unmount mounted directories in /var/lib/kubelet: %s\n", string(umountOutputBytes))
|
||||
}
|
||||
|
||||
dockerCheck := preflight.ServiceCheck{Service: "docker", CheckIfActive: true}
|
||||
if _, errors := dockerCheck.Check(); len(errors) == 0 {
|
||||
fmt.Println("[reset] Removing kubernetes-managed containers")
|
||||
if err := exec.Command("sh", "-c", "docker ps -a --filter name=k8s_ -q | xargs -r docker rm --force --volumes").Run(); err != nil {
|
||||
fmt.Println("[reset] Failed to stop the running containers")
|
||||
}
|
||||
} else {
|
||||
fmt.Println("[reset] docker doesn't seem to be running, skipping the removal of running kubernetes containers")
|
||||
}
|
||||
|
||||
dirsToClean := []string{"/var/lib/kubelet", "/etc/cni/net.d", "/var/lib/dockershim", "/var/run/kubernetes"}
|
||||
|
||||
// Only clear etcd data when the etcd manifest is found. In case it is not found, we must assume that the user
|
||||
// provided external etcd endpoints. In that case, it is his own responsibility to reset etcd
|
||||
etcdManifestPath := filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.ManifestsSubDirName, "etcd.yaml")
|
||||
if _, err := os.Stat(etcdManifestPath); err == nil {
|
||||
dirsToClean = append(dirsToClean, "/var/lib/etcd")
|
||||
} else {
|
||||
fmt.Printf("[reset] No etcd manifest found in %q, assuming external etcd.\n", etcdManifestPath)
|
||||
}
|
||||
|
||||
// Then clean contents from the stateful kubelet, etcd and cni directories
|
||||
fmt.Printf("[reset] Deleting contents of stateful directories: %v\n", dirsToClean)
|
||||
for _, dir := range dirsToClean {
|
||||
cleanDir(dir)
|
||||
}
|
||||
|
||||
// Remove contents from the config and pki directories
|
||||
resetConfigDir(kubeadmconstants.KubernetesDir, r.certsDir)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// cleanDir removes everything in a directory, but not the directory itself
|
||||
func cleanDir(filePath string) error {
|
||||
// If the directory doesn't even exist there's nothing to do, and we do
|
||||
// not consider this an error
|
||||
if _, err := os.Stat(filePath); os.IsNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
|
||||
d, err := os.Open(filePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer d.Close()
|
||||
names, err := d.Readdirnames(-1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, name := range names {
|
||||
if err = os.RemoveAll(filepath.Join(filePath, name)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// resetConfigDir is used to cleanup the files kubeadm writes in /etc/kubernetes/.
|
||||
func resetConfigDir(configPathDir, pkiPathDir string) {
|
||||
dirsToClean := []string{
|
||||
filepath.Join(configPathDir, kubeadmconstants.ManifestsSubDirName),
|
||||
pkiPathDir,
|
||||
}
|
||||
fmt.Printf("[reset] Deleting contents of config directories: %v\n", dirsToClean)
|
||||
for _, dir := range dirsToClean {
|
||||
if err := cleanDir(dir); err != nil {
|
||||
fmt.Printf("[reset] Failed to remove directory: %q [%v]\n", dir, err)
|
||||
}
|
||||
}
|
||||
|
||||
filesToClean := []string{
|
||||
filepath.Join(configPathDir, kubeadmconstants.AdminKubeConfigFileName),
|
||||
filepath.Join(configPathDir, kubeadmconstants.KubeletKubeConfigFileName),
|
||||
filepath.Join(configPathDir, kubeadmconstants.ControllerManagerKubeConfigFileName),
|
||||
filepath.Join(configPathDir, kubeadmconstants.SchedulerKubeConfigFileName),
|
||||
}
|
||||
fmt.Printf("[reset] Deleting files: %v\n", filesToClean)
|
||||
for _, path := range filesToClean {
|
||||
if err := os.RemoveAll(path); err != nil {
|
||||
fmt.Printf("[reset] Failed to remove file: %q [%v]\n", path, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
183
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/reset_test.go
generated
vendored
Normal file
183
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/reset_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
/*
|
||||
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 cmd
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/preflight"
|
||||
)
|
||||
|
||||
func assertExists(t *testing.T, path string) {
|
||||
if _, err := os.Stat(path); os.IsNotExist(err) {
|
||||
t.Errorf("file/dir does not exist error: %s", err)
|
||||
t.Errorf("file/dir does not exist: %s", path)
|
||||
}
|
||||
}
|
||||
|
||||
func assertNotExists(t *testing.T, path string) {
|
||||
if _, err := os.Stat(path); err == nil {
|
||||
t.Errorf("file/dir exists: %s", path)
|
||||
}
|
||||
}
|
||||
|
||||
// assertDirEmpty verifies a directory either does not exist, or is empty.
|
||||
func assertDirEmpty(t *testing.T, path string) {
|
||||
dac := preflight.DirAvailableCheck{Path: path}
|
||||
_, errors := dac.Check()
|
||||
if len(errors) != 0 {
|
||||
t.Errorf("directory not empty: [%v]", errors)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigDirCleaner(t *testing.T) {
|
||||
tests := map[string]struct {
|
||||
setupDirs []string
|
||||
setupFiles []string
|
||||
verifyExists []string
|
||||
verifyNotExists []string
|
||||
}{
|
||||
"simple reset": {
|
||||
setupDirs: []string{
|
||||
"manifests",
|
||||
"pki",
|
||||
},
|
||||
setupFiles: []string{
|
||||
"manifests/etcd.yaml",
|
||||
"manifests/kube-apiserver.yaml",
|
||||
"pki/ca.pem",
|
||||
kubeadmconstants.AdminKubeConfigFileName,
|
||||
kubeadmconstants.KubeletKubeConfigFileName,
|
||||
},
|
||||
verifyExists: []string{
|
||||
"manifests",
|
||||
"pki",
|
||||
},
|
||||
},
|
||||
"partial reset": {
|
||||
setupDirs: []string{
|
||||
"pki",
|
||||
},
|
||||
setupFiles: []string{
|
||||
"pki/ca.pem",
|
||||
kubeadmconstants.KubeletKubeConfigFileName,
|
||||
},
|
||||
verifyExists: []string{
|
||||
"pki",
|
||||
},
|
||||
verifyNotExists: []string{
|
||||
"manifests",
|
||||
},
|
||||
},
|
||||
"preserve cloud-config": {
|
||||
setupDirs: []string{
|
||||
"manifests",
|
||||
"pki",
|
||||
},
|
||||
setupFiles: []string{
|
||||
"manifests/etcd.yaml",
|
||||
"manifests/kube-apiserver.yaml",
|
||||
"pki/ca.pem",
|
||||
kubeadmconstants.AdminKubeConfigFileName,
|
||||
kubeadmconstants.KubeletKubeConfigFileName,
|
||||
"cloud-config",
|
||||
},
|
||||
verifyExists: []string{
|
||||
"manifests",
|
||||
"pki",
|
||||
"cloud-config",
|
||||
},
|
||||
},
|
||||
"preserve hidden files and directories": {
|
||||
setupDirs: []string{
|
||||
"manifests",
|
||||
"pki",
|
||||
".mydir",
|
||||
},
|
||||
setupFiles: []string{
|
||||
"manifests/etcd.yaml",
|
||||
"manifests/kube-apiserver.yaml",
|
||||
"pki/ca.pem",
|
||||
kubeadmconstants.AdminKubeConfigFileName,
|
||||
kubeadmconstants.KubeletKubeConfigFileName,
|
||||
".cloud-config",
|
||||
".mydir/.myfile",
|
||||
},
|
||||
verifyExists: []string{
|
||||
"manifests",
|
||||
"pki",
|
||||
".cloud-config",
|
||||
".mydir",
|
||||
".mydir/.myfile",
|
||||
},
|
||||
},
|
||||
"no-op reset": {
|
||||
verifyNotExists: []string{
|
||||
"pki",
|
||||
"manifests",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for name, test := range tests {
|
||||
t.Logf("Running test: %s", name)
|
||||
|
||||
// Create a temporary directory for our fake config dir:
|
||||
tmpDir, err := ioutil.TempDir("", "kubeadm-reset-test")
|
||||
if err != nil {
|
||||
t.Errorf("Unable to create temp directory: %s", err)
|
||||
}
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
for _, createDir := range test.setupDirs {
|
||||
err := os.Mkdir(filepath.Join(tmpDir, createDir), 0700)
|
||||
if err != nil {
|
||||
t.Errorf("Unable to setup test config directory: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
for _, createFile := range test.setupFiles {
|
||||
fullPath := filepath.Join(tmpDir, createFile)
|
||||
f, err := os.Create(fullPath)
|
||||
if err != nil {
|
||||
t.Errorf("Unable to create test file: %s", err)
|
||||
}
|
||||
defer f.Close()
|
||||
}
|
||||
|
||||
resetConfigDir(tmpDir, filepath.Join(tmpDir, "pki"))
|
||||
|
||||
// Verify the files we cleanup implicitly in every test:
|
||||
assertExists(t, tmpDir)
|
||||
assertNotExists(t, filepath.Join(tmpDir, kubeadmconstants.AdminKubeConfigFileName))
|
||||
assertNotExists(t, filepath.Join(tmpDir, kubeadmconstants.KubeletKubeConfigFileName))
|
||||
assertDirEmpty(t, filepath.Join(tmpDir, "manifests"))
|
||||
assertDirEmpty(t, filepath.Join(tmpDir, "pki"))
|
||||
|
||||
// Verify the files as requested by the test:
|
||||
for _, path := range test.verifyExists {
|
||||
assertExists(t, filepath.Join(tmpDir, path))
|
||||
}
|
||||
for _, path := range test.verifyNotExists {
|
||||
assertNotExists(t, filepath.Join(tmpDir, path))
|
||||
}
|
||||
}
|
||||
}
|
||||
374
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/token.go
generated
vendored
Normal file
374
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/token.go
generated
vendored
Normal file
|
|
@ -0,0 +1,374 @@
|
|||
/*
|
||||
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 cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
"text/tabwriter"
|
||||
"time"
|
||||
|
||||
"github.com/renstrom/dedent"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
|
||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
tokenphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/bootstraptoken/node"
|
||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient"
|
||||
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
|
||||
tokenutil "k8s.io/kubernetes/cmd/kubeadm/app/util/token"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
bootstrapapi "k8s.io/kubernetes/pkg/bootstrap/api"
|
||||
"k8s.io/kubernetes/pkg/printers"
|
||||
)
|
||||
|
||||
func NewCmdToken(out io.Writer, errW io.Writer) *cobra.Command {
|
||||
|
||||
var kubeConfigFile string
|
||||
var dryRun bool
|
||||
tokenCmd := &cobra.Command{
|
||||
Use: "token",
|
||||
Short: "Manage bootstrap tokens.",
|
||||
Long: dedent.Dedent(`
|
||||
This command will manage Bootstrap Token for you.
|
||||
Please note this usage of this command is optional, and mostly for advanced users.
|
||||
|
||||
In short, Bootstrap Tokens are used for establishing bidirectional trust between a client and a server.
|
||||
A Bootstrap Token can be used when a client (for example a node that's about to join the cluster) needs
|
||||
to trust the server it is talking to. Then a Bootstrap Token with the "signing" usage can be used.
|
||||
Bootstrap Tokens can also function as a way to allow short-lived authentication to the API Server
|
||||
(the token serves as a way for the API Server to trust the client), for example for doing the TLS Bootstrap.
|
||||
|
||||
What is a Bootstrap Token more exactly?
|
||||
- It is a Secret in the kube-system namespace of type "bootstrap.kubernetes.io/token".
|
||||
- A Bootstrap Token must be of the form "[a-z0-9]{6}.[a-z0-9]{16}"; the former part is the public Token ID,
|
||||
and the latter is the Token Secret, which must be kept private at all circumstances.
|
||||
- The name of the Secret must be named "bootstrap-token-(token-id)".
|
||||
|
||||
You can read more about Bootstrap Tokens in this proposal:
|
||||
|
||||
https://git.k8s.io/community/contributors/design-proposals/bootstrap-discovery.md
|
||||
`),
|
||||
|
||||
// Without this callback, if a user runs just the "token"
|
||||
// command without a subcommand, or with an invalid subcommand,
|
||||
// cobra will print usage information, but still exit cleanly.
|
||||
// We want to return an error code in these cases so that the
|
||||
// user knows that their command was invalid.
|
||||
RunE: cmdutil.SubCmdRunE("token"),
|
||||
}
|
||||
|
||||
tokenCmd.PersistentFlags().StringVar(&kubeConfigFile,
|
||||
"kubeconfig", "/etc/kubernetes/admin.conf", "The KubeConfig file to use for talking to the cluster")
|
||||
tokenCmd.PersistentFlags().BoolVar(&dryRun,
|
||||
"dry-run", dryRun, "Whether to enable dry-run mode or not")
|
||||
|
||||
var usages []string
|
||||
var extraGroups []string
|
||||
var tokenDuration time.Duration
|
||||
var description string
|
||||
createCmd := &cobra.Command{
|
||||
Use: "create [token]",
|
||||
Short: "Create bootstrap tokens on the server.",
|
||||
Long: dedent.Dedent(`
|
||||
This command will create a Bootstrap Token for you.
|
||||
You can specify the usages for this token, the time to live and an optional human friendly description.
|
||||
|
||||
The [token] is the actual token to write.
|
||||
This should be a securely generated random token of the form "[a-z0-9]{6}.[a-z0-9]{16}".
|
||||
If no [token] is given, kubeadm will generate a random token instead.
|
||||
`),
|
||||
Run: func(tokenCmd *cobra.Command, args []string) {
|
||||
token := ""
|
||||
if len(args) != 0 {
|
||||
token = args[0]
|
||||
}
|
||||
client, err := getClientset(kubeConfigFile, dryRun)
|
||||
kubeadmutil.CheckErr(err)
|
||||
|
||||
// TODO: remove this warning in 1.9
|
||||
if !tokenCmd.Flags().Lookup("ttl").Changed {
|
||||
// sending this output to stderr s
|
||||
fmt.Fprintln(errW, "[kubeadm] WARNING: starting in 1.8, tokens expire after 24 hours by default (if you require a non-expiring token use --ttl 0)")
|
||||
}
|
||||
|
||||
err = RunCreateToken(out, client, token, tokenDuration, usages, extraGroups, description)
|
||||
kubeadmutil.CheckErr(err)
|
||||
},
|
||||
}
|
||||
createCmd.Flags().DurationVar(&tokenDuration,
|
||||
"ttl", kubeadmconstants.DefaultTokenDuration, "The duration before the token is automatically deleted (e.g. 1s, 2m, 3h). 0 means 'never expires'.")
|
||||
createCmd.Flags().StringSliceVar(&usages,
|
||||
"usages", kubeadmconstants.DefaultTokenUsages, "The ways in which this token can be used. Valid options: [signing,authentication].")
|
||||
createCmd.Flags().StringSliceVar(&extraGroups,
|
||||
"groups", []string{},
|
||||
fmt.Sprintf("Extra groups that this token will authenticate as when used for authentication. Must match %q.", bootstrapapi.BootstrapGroupPattern))
|
||||
createCmd.Flags().StringVar(&description,
|
||||
"description", "", "A human friendly description of how this token is used.")
|
||||
tokenCmd.AddCommand(createCmd)
|
||||
|
||||
tokenCmd.AddCommand(NewCmdTokenGenerate(out))
|
||||
|
||||
listCmd := &cobra.Command{
|
||||
Use: "list",
|
||||
Short: "List bootstrap tokens on the server.",
|
||||
Long: dedent.Dedent(`
|
||||
This command will list all Bootstrap Tokens for you.
|
||||
`),
|
||||
Run: func(tokenCmd *cobra.Command, args []string) {
|
||||
client, err := getClientset(kubeConfigFile, dryRun)
|
||||
kubeadmutil.CheckErr(err)
|
||||
|
||||
err = RunListTokens(out, errW, client)
|
||||
kubeadmutil.CheckErr(err)
|
||||
},
|
||||
}
|
||||
tokenCmd.AddCommand(listCmd)
|
||||
|
||||
deleteCmd := &cobra.Command{
|
||||
Use: "delete [token-value]",
|
||||
Short: "Delete bootstrap tokens on the server.",
|
||||
Long: dedent.Dedent(`
|
||||
This command will delete a given Bootstrap Token for you.
|
||||
|
||||
The [token-value] is the full Token of the form "[a-z0-9]{6}.[a-z0-9]{16}" or the
|
||||
Token ID of the form "[a-z0-9]{6}" to delete.
|
||||
`),
|
||||
Run: func(tokenCmd *cobra.Command, args []string) {
|
||||
if len(args) < 1 {
|
||||
kubeadmutil.CheckErr(fmt.Errorf("missing subcommand; 'token delete' is missing token of form [%q]", tokenutil.TokenIDRegexpString))
|
||||
}
|
||||
client, err := getClientset(kubeConfigFile, dryRun)
|
||||
kubeadmutil.CheckErr(err)
|
||||
|
||||
err = RunDeleteToken(out, client, args[0])
|
||||
kubeadmutil.CheckErr(err)
|
||||
},
|
||||
}
|
||||
tokenCmd.AddCommand(deleteCmd)
|
||||
|
||||
return tokenCmd
|
||||
}
|
||||
|
||||
func NewCmdTokenGenerate(out io.Writer) *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "generate",
|
||||
Short: "Generate and print a bootstrap token, but do not create it on the server.",
|
||||
Long: dedent.Dedent(`
|
||||
This command will print out a randomly-generated bootstrap token that can be used with
|
||||
the "init" and "join" commands.
|
||||
|
||||
You don't have to use this command in order to generate a token, you can do so
|
||||
yourself as long as it's in the format "[a-z0-9]{6}.[a-z0-9]{16}". This
|
||||
command is provided for convenience to generate tokens in that format.
|
||||
|
||||
You can also use "kubeadm init" without specifying a token, and it will
|
||||
generate and print one for you.
|
||||
`),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
err := RunGenerateToken(out)
|
||||
kubeadmutil.CheckErr(err)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// RunCreateToken generates a new bootstrap token and stores it as a secret on the server.
|
||||
func RunCreateToken(out io.Writer, client clientset.Interface, token string, tokenDuration time.Duration, usages []string, extraGroups []string, description string) error {
|
||||
|
||||
if len(token) == 0 {
|
||||
var err error
|
||||
token, err = tokenutil.GenerateToken()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
_, _, err := tokenutil.ParseToken(token)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// adding groups only makes sense for authentication
|
||||
usagesSet := sets.NewString(usages...)
|
||||
if len(extraGroups) > 0 && !usagesSet.Has("authentication") {
|
||||
return fmt.Errorf("--groups cannot be specified unless --usages includes \"authentication\"")
|
||||
}
|
||||
|
||||
// validate any extra group names
|
||||
for _, group := range extraGroups {
|
||||
if err := bootstrapapi.ValidateBootstrapGroupName(group); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Validate usages here so we don't allow something unsupported
|
||||
err := tokenphase.CreateNewToken(client, token, tokenDuration, usages, extraGroups, description)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Fprintln(out, token)
|
||||
return nil
|
||||
}
|
||||
|
||||
// RunGenerateToken just generates a random token for the user
|
||||
func RunGenerateToken(out io.Writer) error {
|
||||
token, err := tokenutil.GenerateToken()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Fprintln(out, token)
|
||||
return nil
|
||||
}
|
||||
|
||||
// RunListTokens lists details on all existing bootstrap tokens on the server.
|
||||
func RunListTokens(out io.Writer, errW io.Writer, client clientset.Interface) error {
|
||||
// First, build our selector for bootstrap tokens only
|
||||
tokenSelector := fields.SelectorFromSet(
|
||||
map[string]string{
|
||||
api.SecretTypeField: string(bootstrapapi.SecretTypeBootstrapToken),
|
||||
},
|
||||
)
|
||||
listOptions := metav1.ListOptions{
|
||||
FieldSelector: tokenSelector.String(),
|
||||
}
|
||||
|
||||
secrets, err := client.CoreV1().Secrets(metav1.NamespaceSystem).List(listOptions)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to list bootstrap tokens [%v]", err)
|
||||
}
|
||||
|
||||
w := tabwriter.NewWriter(out, 10, 4, 3, ' ', 0)
|
||||
fmt.Fprintln(w, "TOKEN\tTTL\tEXPIRES\tUSAGES\tDESCRIPTION\tEXTRA GROUPS")
|
||||
for _, secret := range secrets.Items {
|
||||
tokenId := getSecretString(&secret, bootstrapapi.BootstrapTokenIDKey)
|
||||
if len(tokenId) == 0 {
|
||||
fmt.Fprintf(errW, "bootstrap token has no token-id data: %s\n", secret.Name)
|
||||
continue
|
||||
}
|
||||
|
||||
// enforce the right naming convention
|
||||
if secret.Name != fmt.Sprintf("%s%s", bootstrapapi.BootstrapTokenSecretPrefix, tokenId) {
|
||||
fmt.Fprintf(errW, "bootstrap token name is not of the form '%s(token-id)': %s\n", bootstrapapi.BootstrapTokenSecretPrefix, secret.Name)
|
||||
continue
|
||||
}
|
||||
|
||||
tokenSecret := getSecretString(&secret, bootstrapapi.BootstrapTokenSecretKey)
|
||||
if len(tokenSecret) == 0 {
|
||||
fmt.Fprintf(errW, "bootstrap token has no token-secret data: %s\n", secret.Name)
|
||||
continue
|
||||
}
|
||||
td := &kubeadmapi.TokenDiscovery{ID: tokenId, Secret: tokenSecret}
|
||||
|
||||
// Expiration time is optional, if not specified this implies the token
|
||||
// never expires.
|
||||
ttl := "<forever>"
|
||||
expires := "<never>"
|
||||
secretExpiration := getSecretString(&secret, bootstrapapi.BootstrapTokenExpirationKey)
|
||||
if len(secretExpiration) > 0 {
|
||||
expireTime, err := time.Parse(time.RFC3339, secretExpiration)
|
||||
if err != nil {
|
||||
fmt.Fprintf(errW, "can't parse expiration time of bootstrap token %s\n", secret.Name)
|
||||
continue
|
||||
}
|
||||
ttl = printers.ShortHumanDuration(expireTime.Sub(time.Now()))
|
||||
expires = expireTime.Format(time.RFC3339)
|
||||
}
|
||||
|
||||
usages := []string{}
|
||||
for k, v := range secret.Data {
|
||||
// Skip all fields that don't include this prefix
|
||||
if !strings.Contains(k, bootstrapapi.BootstrapTokenUsagePrefix) {
|
||||
continue
|
||||
}
|
||||
// Skip those that don't have this usage set to true
|
||||
if string(v) != "true" {
|
||||
continue
|
||||
}
|
||||
usages = append(usages, strings.TrimPrefix(k, bootstrapapi.BootstrapTokenUsagePrefix))
|
||||
}
|
||||
sort.Strings(usages)
|
||||
usageString := strings.Join(usages, ",")
|
||||
if len(usageString) == 0 {
|
||||
usageString = "<none>"
|
||||
}
|
||||
|
||||
description := getSecretString(&secret, bootstrapapi.BootstrapTokenDescriptionKey)
|
||||
if len(description) == 0 {
|
||||
description = "<none>"
|
||||
}
|
||||
|
||||
groups := getSecretString(&secret, bootstrapapi.BootstrapTokenExtraGroupsKey)
|
||||
if len(groups) == 0 {
|
||||
groups = "<none>"
|
||||
}
|
||||
fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\n", tokenutil.BearerToken(td), ttl, expires, usageString, description, groups)
|
||||
}
|
||||
w.Flush()
|
||||
return nil
|
||||
}
|
||||
|
||||
// RunDeleteToken removes a bootstrap token from the server.
|
||||
func RunDeleteToken(out io.Writer, client clientset.Interface, tokenIdOrToken string) error {
|
||||
// Assume the given first argument is a token id and try to parse it
|
||||
tokenId := tokenIdOrToken
|
||||
if err := tokenutil.ParseTokenID(tokenIdOrToken); err != nil {
|
||||
if tokenId, _, err = tokenutil.ParseToken(tokenIdOrToken); err != nil {
|
||||
return fmt.Errorf("given token or token id %q didn't match pattern [%q] or [%q]", tokenIdOrToken, tokenutil.TokenIDRegexpString, tokenutil.TokenRegexpString)
|
||||
}
|
||||
}
|
||||
|
||||
tokenSecretName := fmt.Sprintf("%s%s", bootstrapapi.BootstrapTokenSecretPrefix, tokenId)
|
||||
if err := client.CoreV1().Secrets(metav1.NamespaceSystem).Delete(tokenSecretName, nil); err != nil {
|
||||
return fmt.Errorf("failed to delete bootstrap token [%v]", err)
|
||||
}
|
||||
fmt.Fprintf(out, "bootstrap token with id %q deleted\n", tokenId)
|
||||
return nil
|
||||
}
|
||||
|
||||
func getSecretString(secret *v1.Secret, key string) string {
|
||||
if secret.Data == nil {
|
||||
return ""
|
||||
}
|
||||
if val, ok := secret.Data[key]; ok {
|
||||
return string(val)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func getClientset(file string, dryRun bool) (clientset.Interface, error) {
|
||||
if dryRun {
|
||||
dryRunGetter, err := apiclient.NewClientBackedDryRunGetterFromKubeconfig(file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return apiclient.NewDryRunClient(dryRunGetter, os.Stdout), nil
|
||||
}
|
||||
client, err := kubeconfigutil.ClientSetFromFile(file)
|
||||
return client, err
|
||||
}
|
||||
46
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/token_test.go
generated
vendored
Normal file
46
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/token_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
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 cmd
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"regexp"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
TokenExpectedRegex = "^\\S{6}\\.\\S{16}\n$"
|
||||
)
|
||||
|
||||
func TestRunGenerateToken(t *testing.T) {
|
||||
var buf bytes.Buffer
|
||||
|
||||
err := RunGenerateToken(&buf)
|
||||
if err != nil {
|
||||
t.Errorf("RunGenerateToken returned an error: %v", err)
|
||||
}
|
||||
|
||||
output := buf.String()
|
||||
|
||||
matched, err := regexp.MatchString(TokenExpectedRegex, output)
|
||||
if err != nil {
|
||||
t.Fatalf("encountered an error while trying to match RunGenerateToken's output: %v", err)
|
||||
}
|
||||
if !matched {
|
||||
t.Errorf("RunGenerateToken's output did not match expected regex; wanted: [%s], got: [%s]", TokenExpectedRegex, output)
|
||||
}
|
||||
}
|
||||
60
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/upgrade/BUILD
generated
vendored
Normal file
60
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/upgrade/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"apply.go",
|
||||
"common.go",
|
||||
"plan.go",
|
||||
"upgrade.go",
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||
"//cmd/kubeadm/app/apis/kubeadm/v1alpha1:go_default_library",
|
||||
"//cmd/kubeadm/app/cmd/util:go_default_library",
|
||||
"//cmd/kubeadm/app/constants:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/controlplane:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/upgrade:go_default_library",
|
||||
"//cmd/kubeadm/app/preflight:go_default_library",
|
||||
"//cmd/kubeadm/app/util:go_default_library",
|
||||
"//cmd/kubeadm/app/util/apiclient:go_default_library",
|
||||
"//cmd/kubeadm/app/util/dryrun:go_default_library",
|
||||
"//cmd/kubeadm/app/util/kubeconfig:go_default_library",
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/util/version:go_default_library",
|
||||
"//vendor/github.com/ghodss/yaml:go_default_library",
|
||||
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||
"//vendor/k8s.io/client-go/discovery/fake:go_default_library",
|
||||
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"apply_test.go",
|
||||
"common_test.go",
|
||||
"plan_test.go",
|
||||
],
|
||||
library = ":go_default_library",
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/apis/kubeadm/v1alpha1:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/upgrade:go_default_library",
|
||||
"//pkg/util/version:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
269
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/upgrade/apply.go
generated
vendored
Normal file
269
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/upgrade/apply.go
generated
vendored
Normal file
|
|
@ -0,0 +1,269 @@
|
|||
/*
|
||||
Copyright 2017 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 upgrade
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/phases/controlplane"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/phases/upgrade"
|
||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient"
|
||||
dryrunutil "k8s.io/kubernetes/cmd/kubeadm/app/util/dryrun"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/util/version"
|
||||
)
|
||||
|
||||
const (
|
||||
upgradeManifestTimeout = 1 * time.Minute
|
||||
)
|
||||
|
||||
// applyFlags holds the information about the flags that can be passed to apply
|
||||
type applyFlags struct {
|
||||
nonInteractiveMode bool
|
||||
force bool
|
||||
dryRun bool
|
||||
newK8sVersionStr string
|
||||
newK8sVersion *version.Version
|
||||
imagePullTimeout time.Duration
|
||||
parent *cmdUpgradeFlags
|
||||
}
|
||||
|
||||
// SessionIsInteractive returns true if the session is of an interactive type (the default, can be opted out of with -y, -f or --dry-run)
|
||||
func (f *applyFlags) SessionIsInteractive() bool {
|
||||
return !f.nonInteractiveMode
|
||||
}
|
||||
|
||||
// NewCmdApply returns the cobra command for `kubeadm upgrade apply`
|
||||
func NewCmdApply(parentFlags *cmdUpgradeFlags) *cobra.Command {
|
||||
flags := &applyFlags{
|
||||
parent: parentFlags,
|
||||
imagePullTimeout: 15 * time.Minute,
|
||||
}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "apply [version]",
|
||||
Short: "Upgrade your Kubernetes cluster to the specified version",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
// Ensure the user is root
|
||||
err := runPreflightChecks(flags.parent.skipPreFlight)
|
||||
kubeadmutil.CheckErr(err)
|
||||
|
||||
err = cmdutil.ValidateExactArgNumber(args, []string{"version"})
|
||||
kubeadmutil.CheckErr(err)
|
||||
|
||||
// It's safe to use args[0] here as the slice has been validated above
|
||||
flags.newK8sVersionStr = args[0]
|
||||
|
||||
// Default the flags dynamically, based on each others' value
|
||||
err = SetImplicitFlags(flags)
|
||||
kubeadmutil.CheckErr(err)
|
||||
|
||||
err = RunApply(flags)
|
||||
kubeadmutil.CheckErr(err)
|
||||
},
|
||||
}
|
||||
|
||||
// Specify the valid flags specific for apply
|
||||
cmd.Flags().BoolVarP(&flags.nonInteractiveMode, "yes", "y", flags.nonInteractiveMode, "Perform the upgrade and do not prompt for confirmation (non-interactive mode).")
|
||||
cmd.Flags().BoolVarP(&flags.force, "force", "f", flags.force, "Force upgrading although some requirements might not be met. This also implies non-interactive mode.")
|
||||
cmd.Flags().BoolVar(&flags.dryRun, "dry-run", flags.dryRun, "Do not change any state, just output what actions would be applied.")
|
||||
cmd.Flags().DurationVar(&flags.imagePullTimeout, "image-pull-timeout", flags.imagePullTimeout, "The maximum amount of time to wait for the control plane pods to be downloaded.")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
// RunApply takes care of the actual upgrade functionality
|
||||
// It does the following things:
|
||||
// - Checks if the cluster is healthy
|
||||
// - Gets the configuration from the kubeadm-config ConfigMap in the cluster
|
||||
// - Enforces all version skew policies
|
||||
// - Asks the user if they really want to upgrade
|
||||
// - Makes sure the control plane images are available locally on the master(s)
|
||||
// - Upgrades the control plane components
|
||||
// - Applies the other resources that'd be created with kubeadm init as well, like
|
||||
// - Creating the RBAC rules for the Bootstrap Tokens and the cluster-info ConfigMap
|
||||
// - Applying new kube-dns and kube-proxy manifests
|
||||
// - Uploads the newly used configuration to the cluster ConfigMap
|
||||
func RunApply(flags *applyFlags) error {
|
||||
|
||||
// Start with the basics, verify that the cluster is healthy and get the configuration from the cluster (using the ConfigMap)
|
||||
upgradeVars, err := enforceRequirements(flags.parent.kubeConfigPath, flags.parent.cfgPath, flags.parent.printConfig, flags.dryRun)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Set the upgraded version on the external config object now
|
||||
upgradeVars.cfg.KubernetesVersion = flags.newK8sVersionStr
|
||||
|
||||
// Grab the external, versioned configuration and convert it to the internal type for usage here later
|
||||
internalcfg := &kubeadmapi.MasterConfiguration{}
|
||||
api.Scheme.Convert(upgradeVars.cfg, internalcfg, nil)
|
||||
|
||||
// Enforce the version skew policies
|
||||
if err := EnforceVersionPolicies(flags, upgradeVars.versionGetter); err != nil {
|
||||
return fmt.Errorf("[upgrade/version] FATAL: %v", err)
|
||||
}
|
||||
|
||||
// If the current session is interactive, ask the user whether they really want to upgrade
|
||||
if flags.SessionIsInteractive() {
|
||||
if err := InteractivelyConfirmUpgrade("Are you sure you want to proceed with the upgrade?"); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Use a prepuller implementation based on creating DaemonSets
|
||||
// and block until all DaemonSets are ready; then we know for sure that all control plane images are cached locally
|
||||
prepuller := upgrade.NewDaemonSetPrepuller(upgradeVars.client, upgradeVars.waiter, internalcfg)
|
||||
upgrade.PrepullImagesInParallel(prepuller, flags.imagePullTimeout)
|
||||
|
||||
// Now; perform the upgrade procedure
|
||||
if err := PerformControlPlaneUpgrade(flags, upgradeVars.client, upgradeVars.waiter, internalcfg); err != nil {
|
||||
return fmt.Errorf("[upgrade/apply] FATAL: %v", err)
|
||||
}
|
||||
|
||||
// Upgrade RBAC rules and addons. Optionally, if needed, perform some extra task for a specific version
|
||||
if err := upgrade.PerformPostUpgradeTasks(upgradeVars.client, internalcfg, flags.newK8sVersion); err != nil {
|
||||
return fmt.Errorf("[upgrade/postupgrade] FATAL post-upgrade error: %v", err)
|
||||
}
|
||||
|
||||
if flags.dryRun {
|
||||
fmt.Println("[dryrun] Finished dryrunning successfully!")
|
||||
return nil
|
||||
}
|
||||
|
||||
fmt.Println("")
|
||||
fmt.Printf("[upgrade/successful] SUCCESS! Your cluster was upgraded to %q. Enjoy!\n", flags.newK8sVersionStr)
|
||||
fmt.Println("")
|
||||
fmt.Println("[upgrade/kubelet] Now that your control plane is upgraded, please proceed with upgrading your kubelets in turn.")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetImplicitFlags handles dynamically defaulting flags based on each other's value
|
||||
func SetImplicitFlags(flags *applyFlags) error {
|
||||
// If we are in dry-run or force mode; we should automatically execute this command non-interactively
|
||||
if flags.dryRun || flags.force {
|
||||
flags.nonInteractiveMode = true
|
||||
}
|
||||
|
||||
k8sVer, err := version.ParseSemantic(flags.newK8sVersionStr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("couldn't parse version %q as a semantic version", flags.newK8sVersionStr)
|
||||
}
|
||||
flags.newK8sVersion = k8sVer
|
||||
|
||||
// Automatically add the "v" prefix to the string representation in case it doesn't exist
|
||||
if !strings.HasPrefix(flags.newK8sVersionStr, "v") {
|
||||
flags.newK8sVersionStr = fmt.Sprintf("v%s", flags.newK8sVersionStr)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// EnforceVersionPolicies makes sure that the version the user specified is valid to upgrade to
|
||||
// There are both fatal and skippable (with --force) errors
|
||||
func EnforceVersionPolicies(flags *applyFlags, versionGetter upgrade.VersionGetter) error {
|
||||
fmt.Printf("[upgrade/version] You have chosen to upgrade to version %q\n", flags.newK8sVersionStr)
|
||||
|
||||
versionSkewErrs := upgrade.EnforceVersionPolicies(versionGetter, flags.newK8sVersionStr, flags.newK8sVersion, flags.parent.allowExperimentalUpgrades, flags.parent.allowRCUpgrades)
|
||||
if versionSkewErrs != nil {
|
||||
|
||||
if len(versionSkewErrs.Mandatory) > 0 {
|
||||
return fmt.Errorf("The --version argument is invalid due to these fatal errors: %v", versionSkewErrs.Mandatory)
|
||||
}
|
||||
|
||||
if len(versionSkewErrs.Skippable) > 0 {
|
||||
// Return the error if the user hasn't specified the --force flag
|
||||
if !flags.force {
|
||||
return fmt.Errorf("The --version argument is invalid due to these errors: %v. Can be bypassed if you pass the --force flag", versionSkewErrs.Skippable)
|
||||
}
|
||||
// Soft errors found, but --force was specified
|
||||
fmt.Printf("[upgrade/version] Found %d potential version compatibility errors but skipping since the --force flag is set: %v\n", len(versionSkewErrs.Skippable), versionSkewErrs.Skippable)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// PerformControlPlaneUpgrade actually performs the upgrade procedure for the cluster of your type (self-hosted or static-pod-hosted)
|
||||
func PerformControlPlaneUpgrade(flags *applyFlags, client clientset.Interface, waiter apiclient.Waiter, internalcfg *kubeadmapi.MasterConfiguration) error {
|
||||
|
||||
// Check if the cluster is self-hosted and act accordingly
|
||||
if upgrade.IsControlPlaneSelfHosted(client) {
|
||||
fmt.Printf("[upgrade/apply] Upgrading your Self-Hosted control plane to version %q...\n", flags.newK8sVersionStr)
|
||||
|
||||
// Upgrade the self-hosted cluster
|
||||
return upgrade.SelfHostedControlPlane(client, waiter, internalcfg, flags.newK8sVersion)
|
||||
}
|
||||
|
||||
// OK, the cluster is hosted using static pods. Upgrade a static-pod hosted cluster
|
||||
fmt.Printf("[upgrade/apply] Upgrading your Static Pod-hosted control plane to version %q...\n", flags.newK8sVersionStr)
|
||||
|
||||
if flags.dryRun {
|
||||
return DryRunStaticPodUpgrade(internalcfg)
|
||||
}
|
||||
return PerformStaticPodUpgrade(client, waiter, internalcfg)
|
||||
}
|
||||
|
||||
// PerformStaticPodUpgrade performs the upgrade of the control plane components for a static pod hosted cluster
|
||||
func PerformStaticPodUpgrade(client clientset.Interface, waiter apiclient.Waiter, internalcfg *kubeadmapi.MasterConfiguration) error {
|
||||
pathManager, err := upgrade.NewKubeStaticPodPathManagerUsingTempDirs(constants.GetStaticPodDirectory())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := upgrade.StaticPodControlPlane(waiter, pathManager, internalcfg); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DryRunStaticPodUpgrade fakes an upgrade of the control plane
|
||||
func DryRunStaticPodUpgrade(internalcfg *kubeadmapi.MasterConfiguration) error {
|
||||
|
||||
dryRunManifestDir, err := constants.CreateTempDirForKubeadm("kubeadm-upgrade-dryrun")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer os.RemoveAll(dryRunManifestDir)
|
||||
|
||||
if err := controlplane.CreateInitStaticPodManifestFiles(dryRunManifestDir, internalcfg); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Print the contents of the upgraded manifests and pretend like they were in /etc/kubernetes/manifests
|
||||
files := []dryrunutil.FileToPrint{}
|
||||
for _, component := range constants.MasterComponents {
|
||||
realPath := constants.GetStaticPodFilepath(component, dryRunManifestDir)
|
||||
outputPath := constants.GetStaticPodFilepath(component, constants.GetStaticPodDirectory())
|
||||
files = append(files, dryrunutil.NewFileToPrint(realPath, outputPath))
|
||||
}
|
||||
|
||||
if err := dryrunutil.PrintDryRunFiles(files, os.Stdout); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
194
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/upgrade/apply_test.go
generated
vendored
Normal file
194
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/upgrade/apply_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
/*
|
||||
Copyright 2017 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 upgrade
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/util/version"
|
||||
)
|
||||
|
||||
func TestSetImplicitFlags(t *testing.T) {
|
||||
var tests = []struct {
|
||||
flags *applyFlags
|
||||
expectedFlags applyFlags
|
||||
errExpected bool
|
||||
}{
|
||||
{ // if not dryRun or force is set; the nonInteractiveMode field should not be touched
|
||||
flags: &applyFlags{
|
||||
newK8sVersionStr: "v1.8.0",
|
||||
dryRun: false,
|
||||
force: false,
|
||||
nonInteractiveMode: false,
|
||||
},
|
||||
expectedFlags: applyFlags{
|
||||
newK8sVersionStr: "v1.8.0",
|
||||
newK8sVersion: version.MustParseSemantic("v1.8.0"),
|
||||
dryRun: false,
|
||||
force: false,
|
||||
nonInteractiveMode: false,
|
||||
},
|
||||
},
|
||||
{ // if not dryRun or force is set; the nonInteractiveMode field should not be touched
|
||||
flags: &applyFlags{
|
||||
newK8sVersionStr: "v1.8.0",
|
||||
dryRun: false,
|
||||
force: false,
|
||||
nonInteractiveMode: true,
|
||||
},
|
||||
expectedFlags: applyFlags{
|
||||
newK8sVersionStr: "v1.8.0",
|
||||
newK8sVersion: version.MustParseSemantic("v1.8.0"),
|
||||
dryRun: false,
|
||||
force: false,
|
||||
nonInteractiveMode: true,
|
||||
},
|
||||
},
|
||||
{ // if dryRun or force is set; the nonInteractiveMode field should be set to true
|
||||
flags: &applyFlags{
|
||||
newK8sVersionStr: "v1.8.0",
|
||||
dryRun: true,
|
||||
force: false,
|
||||
nonInteractiveMode: false,
|
||||
},
|
||||
expectedFlags: applyFlags{
|
||||
newK8sVersionStr: "v1.8.0",
|
||||
newK8sVersion: version.MustParseSemantic("v1.8.0"),
|
||||
dryRun: true,
|
||||
force: false,
|
||||
nonInteractiveMode: true,
|
||||
},
|
||||
},
|
||||
{ // if dryRun or force is set; the nonInteractiveMode field should be set to true
|
||||
flags: &applyFlags{
|
||||
newK8sVersionStr: "v1.8.0",
|
||||
dryRun: false,
|
||||
force: true,
|
||||
nonInteractiveMode: false,
|
||||
},
|
||||
expectedFlags: applyFlags{
|
||||
newK8sVersionStr: "v1.8.0",
|
||||
newK8sVersion: version.MustParseSemantic("v1.8.0"),
|
||||
dryRun: false,
|
||||
force: true,
|
||||
nonInteractiveMode: true,
|
||||
},
|
||||
},
|
||||
{ // if dryRun or force is set; the nonInteractiveMode field should be set to true
|
||||
flags: &applyFlags{
|
||||
newK8sVersionStr: "v1.8.0",
|
||||
dryRun: true,
|
||||
force: true,
|
||||
nonInteractiveMode: false,
|
||||
},
|
||||
expectedFlags: applyFlags{
|
||||
newK8sVersionStr: "v1.8.0",
|
||||
newK8sVersion: version.MustParseSemantic("v1.8.0"),
|
||||
dryRun: true,
|
||||
force: true,
|
||||
nonInteractiveMode: true,
|
||||
},
|
||||
},
|
||||
{ // if dryRun or force is set; the nonInteractiveMode field should be set to true
|
||||
flags: &applyFlags{
|
||||
newK8sVersionStr: "v1.8.0",
|
||||
dryRun: true,
|
||||
force: true,
|
||||
nonInteractiveMode: true,
|
||||
},
|
||||
expectedFlags: applyFlags{
|
||||
newK8sVersionStr: "v1.8.0",
|
||||
newK8sVersion: version.MustParseSemantic("v1.8.0"),
|
||||
dryRun: true,
|
||||
force: true,
|
||||
nonInteractiveMode: true,
|
||||
},
|
||||
},
|
||||
{ // if the new version is empty; it should error out
|
||||
flags: &applyFlags{
|
||||
newK8sVersionStr: "",
|
||||
},
|
||||
expectedFlags: applyFlags{
|
||||
newK8sVersionStr: "",
|
||||
},
|
||||
errExpected: true,
|
||||
},
|
||||
{ // if the new version is invalid; it should error out
|
||||
flags: &applyFlags{
|
||||
newK8sVersionStr: "foo",
|
||||
},
|
||||
expectedFlags: applyFlags{
|
||||
newK8sVersionStr: "foo",
|
||||
},
|
||||
errExpected: true,
|
||||
},
|
||||
{ // if the new version is valid but without the "v" prefix; it parse and prepend v
|
||||
flags: &applyFlags{
|
||||
newK8sVersionStr: "1.8.0",
|
||||
},
|
||||
expectedFlags: applyFlags{
|
||||
newK8sVersionStr: "v1.8.0",
|
||||
newK8sVersion: version.MustParseSemantic("v1.8.0"),
|
||||
},
|
||||
errExpected: false,
|
||||
},
|
||||
{ // valid version should succeed
|
||||
flags: &applyFlags{
|
||||
newK8sVersionStr: "v1.8.1",
|
||||
},
|
||||
expectedFlags: applyFlags{
|
||||
newK8sVersionStr: "v1.8.1",
|
||||
newK8sVersion: version.MustParseSemantic("v1.8.1"),
|
||||
},
|
||||
errExpected: false,
|
||||
},
|
||||
{ // valid version should succeed
|
||||
flags: &applyFlags{
|
||||
newK8sVersionStr: "1.8.0-alpha.3",
|
||||
},
|
||||
expectedFlags: applyFlags{
|
||||
newK8sVersionStr: "v1.8.0-alpha.3",
|
||||
newK8sVersion: version.MustParseSemantic("v1.8.0-alpha.3"),
|
||||
},
|
||||
errExpected: false,
|
||||
},
|
||||
}
|
||||
for _, rt := range tests {
|
||||
actualErr := SetImplicitFlags(rt.flags)
|
||||
|
||||
// If an error was returned; make newK8sVersion nil so it's easy to match using reflect.DeepEqual later (instead of a random pointer)
|
||||
if actualErr != nil {
|
||||
rt.flags.newK8sVersion = nil
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(*rt.flags, rt.expectedFlags) {
|
||||
t.Errorf(
|
||||
"failed SetImplicitFlags:\n\texpected flags: %v\n\t actual: %v",
|
||||
rt.expectedFlags,
|
||||
*rt.flags,
|
||||
)
|
||||
}
|
||||
if (actualErr != nil) != rt.errExpected {
|
||||
t.Errorf(
|
||||
"failed SetImplicitFlags:\n\texpected error: %t\n\t actual: %t",
|
||||
rt.errExpected,
|
||||
(actualErr != nil),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
166
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/upgrade/common.go
generated
vendored
Normal file
166
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/upgrade/common.go
generated
vendored
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
Copyright 2017 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 upgrade
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
|
||||
fakediscovery "k8s.io/client-go/discovery/fake"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
kubeadmapiext "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/phases/upgrade"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/preflight"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient"
|
||||
dryrunutil "k8s.io/kubernetes/cmd/kubeadm/app/util/dryrun"
|
||||
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
|
||||
)
|
||||
|
||||
// upgradeVariables holds variables needed for performing an upgrade or planning to do so
|
||||
// TODO - Restructure or rename upgradeVariables
|
||||
type upgradeVariables struct {
|
||||
client clientset.Interface
|
||||
cfg *kubeadmapiext.MasterConfiguration
|
||||
versionGetter upgrade.VersionGetter
|
||||
waiter apiclient.Waiter
|
||||
}
|
||||
|
||||
// enforceRequirements verifies that it's okay to upgrade and then returns the variables needed for the rest of the procedure
|
||||
func enforceRequirements(kubeConfigPath, cfgPath string, printConfig, dryRun bool) (*upgradeVariables, error) {
|
||||
client, err := getClient(kubeConfigPath, dryRun)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("couldn't create a Kubernetes client from file %q: %v", kubeConfigPath, err)
|
||||
}
|
||||
|
||||
// Run healthchecks against the cluster
|
||||
if err := upgrade.CheckClusterHealth(client); err != nil {
|
||||
return nil, fmt.Errorf("[upgrade/health] FATAL: %v", err)
|
||||
}
|
||||
|
||||
// Fetch the configuration from a file or ConfigMap and validate it
|
||||
cfg, err := upgrade.FetchConfiguration(client, os.Stdout, cfgPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("[upgrade/config] FATAL: %v", err)
|
||||
}
|
||||
|
||||
// If the user told us to print this information out; do it!
|
||||
if printConfig {
|
||||
printConfiguration(cfg, os.Stdout)
|
||||
}
|
||||
|
||||
return &upgradeVariables{
|
||||
client: client,
|
||||
cfg: cfg,
|
||||
// Use a real version getter interface that queries the API server, the kubeadm client and the Kubernetes CI system for latest versions
|
||||
versionGetter: upgrade.NewKubeVersionGetter(client, os.Stdout),
|
||||
// Use the waiter conditionally based on the dryrunning variable
|
||||
waiter: getWaiter(dryRun, client),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// printConfiguration prints the external version of the API to yaml
|
||||
func printConfiguration(cfg *kubeadmapiext.MasterConfiguration, w io.Writer) {
|
||||
// Short-circuit if cfg is nil, so we can safely get the value of the pointer below
|
||||
if cfg == nil {
|
||||
return
|
||||
}
|
||||
|
||||
cfgYaml, err := yaml.Marshal(*cfg)
|
||||
if err == nil {
|
||||
fmt.Fprintln(w, "[upgrade/config] Configuration used:")
|
||||
|
||||
scanner := bufio.NewScanner(bytes.NewReader(cfgYaml))
|
||||
for scanner.Scan() {
|
||||
fmt.Fprintf(w, "\t%s\n", scanner.Text())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// runPreflightChecks runs the root preflight check
|
||||
func runPreflightChecks(skipPreFlight bool) error {
|
||||
if skipPreFlight {
|
||||
fmt.Println("[preflight] Skipping pre-flight checks")
|
||||
return nil
|
||||
}
|
||||
|
||||
fmt.Println("[preflight] Running pre-flight checks")
|
||||
return preflight.RunRootCheckOnly()
|
||||
}
|
||||
|
||||
// getClient gets a real or fake client depending on whether the user is dry-running or not
|
||||
func getClient(file string, dryRun bool) (clientset.Interface, error) {
|
||||
if dryRun {
|
||||
dryRunGetter, err := apiclient.NewClientBackedDryRunGetterFromKubeconfig(file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// In order for fakeclient.Discovery().ServerVersion() to return the backing API Server's
|
||||
// real version; we have to do some clever API machinery tricks. First, we get the real
|
||||
// API Server's version
|
||||
realServerVersion, err := dryRunGetter.Client().Discovery().ServerVersion()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get server version: %v", err)
|
||||
}
|
||||
|
||||
// Get the fake clientset
|
||||
fakeclient := apiclient.NewDryRunClient(dryRunGetter, os.Stdout)
|
||||
// As we know the return of Discovery() of the fake clientset is of type *fakediscovery.FakeDiscovery
|
||||
// we can convert it to that struct.
|
||||
fakeclientDiscovery, ok := fakeclient.Discovery().(*fakediscovery.FakeDiscovery)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("couldn't set fake discovery's server version")
|
||||
}
|
||||
// Lastly, set the right server version to be used
|
||||
fakeclientDiscovery.FakedServerVersion = realServerVersion
|
||||
// return the fake clientset used for dry-running
|
||||
return fakeclient, nil
|
||||
}
|
||||
return kubeconfigutil.ClientSetFromFile(file)
|
||||
}
|
||||
|
||||
// getWaiter gets the right waiter implementation
|
||||
func getWaiter(dryRun bool, client clientset.Interface) apiclient.Waiter {
|
||||
if dryRun {
|
||||
return dryrunutil.NewWaiter()
|
||||
}
|
||||
return apiclient.NewKubeWaiter(client, upgradeManifestTimeout, os.Stdout)
|
||||
}
|
||||
|
||||
// InteractivelyConfirmUpgrade asks the user whether they _really_ want to upgrade.
|
||||
func InteractivelyConfirmUpgrade(question string) error {
|
||||
|
||||
fmt.Printf("[upgrade/confirm] %s [y/N]: ", question)
|
||||
|
||||
scanner := bufio.NewScanner(os.Stdin)
|
||||
scanner.Scan()
|
||||
if err := scanner.Err(); err != nil {
|
||||
return fmt.Errorf("couldn't read from standard input: %v", err)
|
||||
}
|
||||
answer := scanner.Text()
|
||||
if strings.ToLower(answer) == "y" || strings.ToLower(answer) == "yes" {
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("won't proceed; the user didn't answer (Y|y) in order to continue")
|
||||
}
|
||||
110
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/upgrade/common_test.go
generated
vendored
Normal file
110
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/upgrade/common_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
Copyright 2017 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 upgrade
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
kubeadmapiext "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1"
|
||||
)
|
||||
|
||||
func TestPrintConfiguration(t *testing.T) {
|
||||
var tests = []struct {
|
||||
cfg *kubeadmapiext.MasterConfiguration
|
||||
buf *bytes.Buffer
|
||||
expectedBytes []byte
|
||||
}{
|
||||
{
|
||||
cfg: nil,
|
||||
expectedBytes: []byte(""),
|
||||
},
|
||||
{
|
||||
cfg: &kubeadmapiext.MasterConfiguration{
|
||||
KubernetesVersion: "v1.7.1",
|
||||
},
|
||||
expectedBytes: []byte(`[upgrade/config] Configuration used:
|
||||
api:
|
||||
advertiseAddress: ""
|
||||
bindPort: 0
|
||||
certificatesDir: ""
|
||||
cloudProvider: ""
|
||||
etcd:
|
||||
caFile: ""
|
||||
certFile: ""
|
||||
dataDir: ""
|
||||
endpoints: null
|
||||
image: ""
|
||||
keyFile: ""
|
||||
imageRepository: ""
|
||||
kubernetesVersion: v1.7.1
|
||||
networking:
|
||||
dnsDomain: ""
|
||||
podSubnet: ""
|
||||
serviceSubnet: ""
|
||||
nodeName: ""
|
||||
token: ""
|
||||
tokenTTL: 0s
|
||||
unifiedControlPlaneImage: ""
|
||||
`),
|
||||
},
|
||||
{
|
||||
cfg: &kubeadmapiext.MasterConfiguration{
|
||||
KubernetesVersion: "v1.7.1",
|
||||
Networking: kubeadmapiext.Networking{
|
||||
ServiceSubnet: "10.96.0.1/12",
|
||||
},
|
||||
},
|
||||
expectedBytes: []byte(`[upgrade/config] Configuration used:
|
||||
api:
|
||||
advertiseAddress: ""
|
||||
bindPort: 0
|
||||
certificatesDir: ""
|
||||
cloudProvider: ""
|
||||
etcd:
|
||||
caFile: ""
|
||||
certFile: ""
|
||||
dataDir: ""
|
||||
endpoints: null
|
||||
image: ""
|
||||
keyFile: ""
|
||||
imageRepository: ""
|
||||
kubernetesVersion: v1.7.1
|
||||
networking:
|
||||
dnsDomain: ""
|
||||
podSubnet: ""
|
||||
serviceSubnet: 10.96.0.1/12
|
||||
nodeName: ""
|
||||
token: ""
|
||||
tokenTTL: 0s
|
||||
unifiedControlPlaneImage: ""
|
||||
`),
|
||||
},
|
||||
}
|
||||
for _, rt := range tests {
|
||||
rt.buf = bytes.NewBufferString("")
|
||||
printConfiguration(rt.cfg, rt.buf)
|
||||
actualBytes := rt.buf.Bytes()
|
||||
if !bytes.Equal(actualBytes, rt.expectedBytes) {
|
||||
t.Errorf(
|
||||
"failed PrintConfiguration:\n\texpected: %q\n\t actual: %q",
|
||||
string(rt.expectedBytes),
|
||||
string(actualBytes),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
142
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/upgrade/plan.go
generated
vendored
Normal file
142
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/upgrade/plan.go
generated
vendored
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
Copyright 2017 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 upgrade
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"sort"
|
||||
"text/tabwriter"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/phases/upgrade"
|
||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||
)
|
||||
|
||||
// NewCmdPlan returns the cobra command for `kubeadm upgrade plan`
|
||||
func NewCmdPlan(parentFlags *cmdUpgradeFlags) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "plan",
|
||||
Short: "Check which versions are available to upgrade to and validate whether your current cluster is upgradeable",
|
||||
Run: func(_ *cobra.Command, _ []string) {
|
||||
// Ensure the user is root
|
||||
err := runPreflightChecks(parentFlags.skipPreFlight)
|
||||
kubeadmutil.CheckErr(err)
|
||||
|
||||
err = RunPlan(parentFlags)
|
||||
kubeadmutil.CheckErr(err)
|
||||
},
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
// RunPlan takes care of outputting available versions to upgrade to for the user
|
||||
func RunPlan(parentFlags *cmdUpgradeFlags) error {
|
||||
|
||||
// Start with the basics, verify that the cluster is healthy, build a client and a versionGetter. Never set dry-run for plan.
|
||||
upgradeVars, err := enforceRequirements(parentFlags.kubeConfigPath, parentFlags.cfgPath, parentFlags.printConfig, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Compute which upgrade possibilities there are
|
||||
availUpgrades, err := upgrade.GetAvailableUpgrades(upgradeVars.versionGetter, parentFlags.allowExperimentalUpgrades, parentFlags.allowRCUpgrades)
|
||||
if err != nil {
|
||||
return fmt.Errorf("[upgrade/versions] FATAL: %v", err)
|
||||
}
|
||||
|
||||
// Tell the user which upgrades are available
|
||||
printAvailableUpgrades(availUpgrades, os.Stdout)
|
||||
return nil
|
||||
}
|
||||
|
||||
// printAvailableUpgrades prints a UX-friendly overview of what versions are available to upgrade to
|
||||
// TODO look into columnize or some other formatter when time permits instead of using the tabwriter
|
||||
func printAvailableUpgrades(upgrades []upgrade.Upgrade, w io.Writer) {
|
||||
|
||||
// Return quickly if no upgrades can be made
|
||||
if len(upgrades) == 0 {
|
||||
fmt.Fprintln(w, "Awesome, you're up-to-date! Enjoy!")
|
||||
return
|
||||
}
|
||||
// The tab writer writes to the "real" writer w
|
||||
tabw := tabwriter.NewWriter(w, 10, 4, 3, ' ', 0)
|
||||
|
||||
// Loop through the upgrade possibilities and output text to the command line
|
||||
for _, upgrade := range upgrades {
|
||||
|
||||
if upgrade.CanUpgradeKubelets() {
|
||||
fmt.Fprintln(w, "Components that must be upgraded manually after you've upgraded the control plane with 'kubeadm upgrade apply':")
|
||||
fmt.Fprintln(tabw, "COMPONENT\tCURRENT\tAVAILABLE")
|
||||
firstPrinted := false
|
||||
|
||||
// The map is of the form <old-version>:<node-count>. Here all the keys are put into a slice and sorted
|
||||
// in order to always get the right order. Then the map value is extracted separately
|
||||
for _, oldVersion := range sortedSliceFromStringIntMap(upgrade.Before.KubeletVersions) {
|
||||
nodeCount := upgrade.Before.KubeletVersions[oldVersion]
|
||||
if !firstPrinted {
|
||||
// Output the Kubelet header only on the first version pair
|
||||
fmt.Fprintf(tabw, "Kubelet\t%d x %s\t%s\n", nodeCount, oldVersion, upgrade.After.KubeVersion)
|
||||
firstPrinted = true
|
||||
continue
|
||||
}
|
||||
fmt.Fprintf(tabw, "\t\t%d x %s\t%s\n", nodeCount, oldVersion, upgrade.After.KubeVersion)
|
||||
}
|
||||
// We should flush the writer here at this stage; as the columns will now be of the right size, adjusted to the above content
|
||||
tabw.Flush()
|
||||
fmt.Fprintln(w, "")
|
||||
}
|
||||
|
||||
fmt.Fprintf(w, "Upgrade to the latest %s:\n", upgrade.Description)
|
||||
fmt.Fprintln(w, "")
|
||||
fmt.Fprintln(tabw, "COMPONENT\tCURRENT\tAVAILABLE")
|
||||
fmt.Fprintf(tabw, "API Server\t%s\t%s\n", upgrade.Before.KubeVersion, upgrade.After.KubeVersion)
|
||||
fmt.Fprintf(tabw, "Controller Manager\t%s\t%s\n", upgrade.Before.KubeVersion, upgrade.After.KubeVersion)
|
||||
fmt.Fprintf(tabw, "Scheduler\t%s\t%s\n", upgrade.Before.KubeVersion, upgrade.After.KubeVersion)
|
||||
fmt.Fprintf(tabw, "Kube Proxy\t%s\t%s\n", upgrade.Before.KubeVersion, upgrade.After.KubeVersion)
|
||||
fmt.Fprintf(tabw, "Kube DNS\t%s\t%s\n", upgrade.Before.DNSVersion, upgrade.After.DNSVersion)
|
||||
|
||||
// The tabwriter should be flushed at this stage as we have now put in all the required content for this time. This is required for the tabs' size to be correct.
|
||||
tabw.Flush()
|
||||
fmt.Fprintln(w, "")
|
||||
fmt.Fprintln(w, "You can now apply the upgrade by executing the following command:")
|
||||
fmt.Fprintln(w, "")
|
||||
fmt.Fprintf(w, "\tkubeadm upgrade apply %s\n", upgrade.After.KubeVersion)
|
||||
fmt.Fprintln(w, "")
|
||||
|
||||
if upgrade.Before.KubeadmVersion != upgrade.After.KubeadmVersion {
|
||||
fmt.Fprintf(w, "Note: Before you do can perform this upgrade, you have to update kubeadm to %s\n", upgrade.After.KubeadmVersion)
|
||||
fmt.Fprintln(w, "")
|
||||
}
|
||||
|
||||
fmt.Fprintln(w, "_____________________________________________________________________")
|
||||
fmt.Fprintln(w, "")
|
||||
}
|
||||
}
|
||||
|
||||
// sortedSliceFromStringIntMap returns a slice of the keys in the map sorted alphabetically
|
||||
func sortedSliceFromStringIntMap(strMap map[string]uint16) []string {
|
||||
strSlice := []string{}
|
||||
for k := range strMap {
|
||||
strSlice = append(strSlice, k)
|
||||
}
|
||||
sort.Strings(strSlice)
|
||||
return strSlice
|
||||
}
|
||||
329
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/upgrade/plan_test.go
generated
vendored
Normal file
329
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/upgrade/plan_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,329 @@
|
|||
/*
|
||||
Copyright 2017 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 upgrade
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/phases/upgrade"
|
||||
)
|
||||
|
||||
func TestSortedSliceFromStringIntMap(t *testing.T) {
|
||||
var tests = []struct {
|
||||
strMap map[string]uint16
|
||||
expectedSlice []string
|
||||
}{ // The returned slice should be alphabetically sorted based on the string keys in the map
|
||||
{
|
||||
strMap: map[string]uint16{"foo": 1, "bar": 2},
|
||||
expectedSlice: []string{"bar", "foo"},
|
||||
},
|
||||
{ // The int value should not affect this func
|
||||
strMap: map[string]uint16{"foo": 2, "bar": 1},
|
||||
expectedSlice: []string{"bar", "foo"},
|
||||
},
|
||||
{
|
||||
strMap: map[string]uint16{"b": 2, "a": 1, "cb": 0, "ca": 1000},
|
||||
expectedSlice: []string{"a", "b", "ca", "cb"},
|
||||
},
|
||||
{ // This should work for version numbers as well; and the lowest version should come first
|
||||
strMap: map[string]uint16{"v1.7.0": 1, "v1.6.1": 1, "v1.6.2": 1, "v1.8.0": 1, "v1.8.0-alpha.1": 1},
|
||||
expectedSlice: []string{"v1.6.1", "v1.6.2", "v1.7.0", "v1.8.0", "v1.8.0-alpha.1"},
|
||||
},
|
||||
}
|
||||
for _, rt := range tests {
|
||||
actualSlice := sortedSliceFromStringIntMap(rt.strMap)
|
||||
if !reflect.DeepEqual(actualSlice, rt.expectedSlice) {
|
||||
t.Errorf(
|
||||
"failed SortedSliceFromStringIntMap:\n\texpected: %v\n\t actual: %v",
|
||||
rt.expectedSlice,
|
||||
actualSlice,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO Think about modifying this test to be less verbose checking b/c it can be brittle.
|
||||
func TestPrintAvailableUpgrades(t *testing.T) {
|
||||
var tests = []struct {
|
||||
upgrades []upgrade.Upgrade
|
||||
buf *bytes.Buffer
|
||||
expectedBytes []byte
|
||||
}{
|
||||
{
|
||||
upgrades: []upgrade.Upgrade{},
|
||||
expectedBytes: []byte(`Awesome, you're up-to-date! Enjoy!
|
||||
`),
|
||||
},
|
||||
{
|
||||
upgrades: []upgrade.Upgrade{
|
||||
{
|
||||
Description: "version in the v1.7 series",
|
||||
Before: upgrade.ClusterState{
|
||||
KubeVersion: "v1.7.1",
|
||||
KubeletVersions: map[string]uint16{
|
||||
"v1.7.1": 1,
|
||||
},
|
||||
KubeadmVersion: "v1.7.2",
|
||||
DNSVersion: "1.14.5",
|
||||
},
|
||||
After: upgrade.ClusterState{
|
||||
KubeVersion: "v1.7.3",
|
||||
KubeadmVersion: "v1.7.3",
|
||||
DNSVersion: "1.14.5",
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedBytes: []byte(`Components that must be upgraded manually after you've upgraded the control plane with 'kubeadm upgrade apply':
|
||||
COMPONENT CURRENT AVAILABLE
|
||||
Kubelet 1 x v1.7.1 v1.7.3
|
||||
|
||||
Upgrade to the latest version in the v1.7 series:
|
||||
|
||||
COMPONENT CURRENT AVAILABLE
|
||||
API Server v1.7.1 v1.7.3
|
||||
Controller Manager v1.7.1 v1.7.3
|
||||
Scheduler v1.7.1 v1.7.3
|
||||
Kube Proxy v1.7.1 v1.7.3
|
||||
Kube DNS 1.14.5 1.14.5
|
||||
|
||||
You can now apply the upgrade by executing the following command:
|
||||
|
||||
kubeadm upgrade apply v1.7.3
|
||||
|
||||
Note: Before you do can perform this upgrade, you have to update kubeadm to v1.7.3
|
||||
|
||||
_____________________________________________________________________
|
||||
|
||||
`),
|
||||
},
|
||||
{
|
||||
upgrades: []upgrade.Upgrade{
|
||||
{
|
||||
Description: "stable version",
|
||||
Before: upgrade.ClusterState{
|
||||
KubeVersion: "v1.7.3",
|
||||
KubeletVersions: map[string]uint16{
|
||||
"v1.7.3": 1,
|
||||
},
|
||||
KubeadmVersion: "v1.8.0",
|
||||
DNSVersion: "1.14.5",
|
||||
},
|
||||
After: upgrade.ClusterState{
|
||||
KubeVersion: "v1.8.0",
|
||||
KubeadmVersion: "v1.8.0",
|
||||
DNSVersion: "1.14.5",
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedBytes: []byte(`Components that must be upgraded manually after you've upgraded the control plane with 'kubeadm upgrade apply':
|
||||
COMPONENT CURRENT AVAILABLE
|
||||
Kubelet 1 x v1.7.3 v1.8.0
|
||||
|
||||
Upgrade to the latest stable version:
|
||||
|
||||
COMPONENT CURRENT AVAILABLE
|
||||
API Server v1.7.3 v1.8.0
|
||||
Controller Manager v1.7.3 v1.8.0
|
||||
Scheduler v1.7.3 v1.8.0
|
||||
Kube Proxy v1.7.3 v1.8.0
|
||||
Kube DNS 1.14.5 1.14.5
|
||||
|
||||
You can now apply the upgrade by executing the following command:
|
||||
|
||||
kubeadm upgrade apply v1.8.0
|
||||
|
||||
_____________________________________________________________________
|
||||
|
||||
`),
|
||||
},
|
||||
{
|
||||
upgrades: []upgrade.Upgrade{
|
||||
{
|
||||
Description: "version in the v1.7 series",
|
||||
Before: upgrade.ClusterState{
|
||||
KubeVersion: "v1.7.3",
|
||||
KubeletVersions: map[string]uint16{
|
||||
"v1.7.3": 1,
|
||||
},
|
||||
KubeadmVersion: "v1.8.1",
|
||||
DNSVersion: "1.14.5",
|
||||
},
|
||||
After: upgrade.ClusterState{
|
||||
KubeVersion: "v1.7.5",
|
||||
KubeadmVersion: "v1.8.1",
|
||||
DNSVersion: "1.14.5",
|
||||
},
|
||||
},
|
||||
{
|
||||
Description: "stable version",
|
||||
Before: upgrade.ClusterState{
|
||||
KubeVersion: "v1.7.3",
|
||||
KubeletVersions: map[string]uint16{
|
||||
"v1.7.3": 1,
|
||||
},
|
||||
KubeadmVersion: "v1.8.1",
|
||||
DNSVersion: "1.14.5",
|
||||
},
|
||||
After: upgrade.ClusterState{
|
||||
KubeVersion: "v1.8.2",
|
||||
KubeadmVersion: "v1.8.2",
|
||||
DNSVersion: "1.14.5",
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedBytes: []byte(`Components that must be upgraded manually after you've upgraded the control plane with 'kubeadm upgrade apply':
|
||||
COMPONENT CURRENT AVAILABLE
|
||||
Kubelet 1 x v1.7.3 v1.7.5
|
||||
|
||||
Upgrade to the latest version in the v1.7 series:
|
||||
|
||||
COMPONENT CURRENT AVAILABLE
|
||||
API Server v1.7.3 v1.7.5
|
||||
Controller Manager v1.7.3 v1.7.5
|
||||
Scheduler v1.7.3 v1.7.5
|
||||
Kube Proxy v1.7.3 v1.7.5
|
||||
Kube DNS 1.14.5 1.14.5
|
||||
|
||||
You can now apply the upgrade by executing the following command:
|
||||
|
||||
kubeadm upgrade apply v1.7.5
|
||||
|
||||
_____________________________________________________________________
|
||||
|
||||
Components that must be upgraded manually after you've upgraded the control plane with 'kubeadm upgrade apply':
|
||||
COMPONENT CURRENT AVAILABLE
|
||||
Kubelet 1 x v1.7.3 v1.8.2
|
||||
|
||||
Upgrade to the latest stable version:
|
||||
|
||||
COMPONENT CURRENT AVAILABLE
|
||||
API Server v1.7.3 v1.8.2
|
||||
Controller Manager v1.7.3 v1.8.2
|
||||
Scheduler v1.7.3 v1.8.2
|
||||
Kube Proxy v1.7.3 v1.8.2
|
||||
Kube DNS 1.14.5 1.14.5
|
||||
|
||||
You can now apply the upgrade by executing the following command:
|
||||
|
||||
kubeadm upgrade apply v1.8.2
|
||||
|
||||
Note: Before you do can perform this upgrade, you have to update kubeadm to v1.8.2
|
||||
|
||||
_____________________________________________________________________
|
||||
|
||||
`),
|
||||
},
|
||||
{
|
||||
upgrades: []upgrade.Upgrade{
|
||||
{
|
||||
Description: "experimental version",
|
||||
Before: upgrade.ClusterState{
|
||||
KubeVersion: "v1.7.5",
|
||||
KubeletVersions: map[string]uint16{
|
||||
"v1.7.5": 1,
|
||||
},
|
||||
KubeadmVersion: "v1.7.5",
|
||||
DNSVersion: "1.14.5",
|
||||
},
|
||||
After: upgrade.ClusterState{
|
||||
KubeVersion: "v1.8.0-beta.1",
|
||||
KubeadmVersion: "v1.8.0-beta.1",
|
||||
DNSVersion: "1.14.5",
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedBytes: []byte(`Components that must be upgraded manually after you've upgraded the control plane with 'kubeadm upgrade apply':
|
||||
COMPONENT CURRENT AVAILABLE
|
||||
Kubelet 1 x v1.7.5 v1.8.0-beta.1
|
||||
|
||||
Upgrade to the latest experimental version:
|
||||
|
||||
COMPONENT CURRENT AVAILABLE
|
||||
API Server v1.7.5 v1.8.0-beta.1
|
||||
Controller Manager v1.7.5 v1.8.0-beta.1
|
||||
Scheduler v1.7.5 v1.8.0-beta.1
|
||||
Kube Proxy v1.7.5 v1.8.0-beta.1
|
||||
Kube DNS 1.14.5 1.14.5
|
||||
|
||||
You can now apply the upgrade by executing the following command:
|
||||
|
||||
kubeadm upgrade apply v1.8.0-beta.1
|
||||
|
||||
Note: Before you do can perform this upgrade, you have to update kubeadm to v1.8.0-beta.1
|
||||
|
||||
_____________________________________________________________________
|
||||
|
||||
`),
|
||||
},
|
||||
{
|
||||
upgrades: []upgrade.Upgrade{
|
||||
{
|
||||
Description: "release candidate version",
|
||||
Before: upgrade.ClusterState{
|
||||
KubeVersion: "v1.7.5",
|
||||
KubeletVersions: map[string]uint16{
|
||||
"v1.7.5": 1,
|
||||
},
|
||||
KubeadmVersion: "v1.7.5",
|
||||
DNSVersion: "1.14.5",
|
||||
},
|
||||
After: upgrade.ClusterState{
|
||||
KubeVersion: "v1.8.0-rc.1",
|
||||
KubeadmVersion: "v1.8.0-rc.1",
|
||||
DNSVersion: "1.14.5",
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedBytes: []byte(`Components that must be upgraded manually after you've upgraded the control plane with 'kubeadm upgrade apply':
|
||||
COMPONENT CURRENT AVAILABLE
|
||||
Kubelet 1 x v1.7.5 v1.8.0-rc.1
|
||||
|
||||
Upgrade to the latest release candidate version:
|
||||
|
||||
COMPONENT CURRENT AVAILABLE
|
||||
API Server v1.7.5 v1.8.0-rc.1
|
||||
Controller Manager v1.7.5 v1.8.0-rc.1
|
||||
Scheduler v1.7.5 v1.8.0-rc.1
|
||||
Kube Proxy v1.7.5 v1.8.0-rc.1
|
||||
Kube DNS 1.14.5 1.14.5
|
||||
|
||||
You can now apply the upgrade by executing the following command:
|
||||
|
||||
kubeadm upgrade apply v1.8.0-rc.1
|
||||
|
||||
Note: Before you do can perform this upgrade, you have to update kubeadm to v1.8.0-rc.1
|
||||
|
||||
_____________________________________________________________________
|
||||
|
||||
`),
|
||||
},
|
||||
}
|
||||
for _, rt := range tests {
|
||||
rt.buf = bytes.NewBufferString("")
|
||||
printAvailableUpgrades(rt.upgrades, rt.buf)
|
||||
actualBytes := rt.buf.Bytes()
|
||||
if !bytes.Equal(actualBytes, rt.expectedBytes) {
|
||||
t.Errorf(
|
||||
"failed PrintAvailableUpgrades:\n\texpected: %q\n\t actual: %q",
|
||||
string(rt.expectedBytes),
|
||||
string(actualBytes),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
64
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/upgrade/upgrade.go
generated
vendored
Normal file
64
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/upgrade/upgrade.go
generated
vendored
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
Copyright 2017 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 upgrade
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
|
||||
)
|
||||
|
||||
// cmdUpgradeFlags holds the values for the common flags in `kubeadm upgrade`
|
||||
type cmdUpgradeFlags struct {
|
||||
kubeConfigPath string
|
||||
cfgPath string
|
||||
allowExperimentalUpgrades bool
|
||||
allowRCUpgrades bool
|
||||
printConfig bool
|
||||
skipPreFlight bool
|
||||
}
|
||||
|
||||
// NewCmdUpgrade returns the cobra command for `kubeadm upgrade`
|
||||
func NewCmdUpgrade(out io.Writer) *cobra.Command {
|
||||
flags := &cmdUpgradeFlags{
|
||||
kubeConfigPath: "/etc/kubernetes/admin.conf",
|
||||
cfgPath: "",
|
||||
allowExperimentalUpgrades: false,
|
||||
allowRCUpgrades: false,
|
||||
printConfig: false,
|
||||
skipPreFlight: false,
|
||||
}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "upgrade",
|
||||
Short: "Upgrade your cluster smoothly to a newer version with this command.",
|
||||
RunE: cmdutil.SubCmdRunE("upgrade"),
|
||||
}
|
||||
|
||||
cmd.PersistentFlags().StringVar(&flags.kubeConfigPath, "kubeconfig", flags.kubeConfigPath, "The KubeConfig file to use for talking to the cluster.")
|
||||
cmd.PersistentFlags().StringVar(&flags.cfgPath, "config", flags.cfgPath, "Path to kubeadm config file (WARNING: Usage of a configuration file is experimental).")
|
||||
cmd.PersistentFlags().BoolVar(&flags.allowExperimentalUpgrades, "allow-experimental-upgrades", flags.allowExperimentalUpgrades, "Show unstable versions of Kubernetes as an upgrade alternative and allow upgrading to an alpha/beta/release candidate versions of Kubernetes.")
|
||||
cmd.PersistentFlags().BoolVar(&flags.allowRCUpgrades, "allow-release-candidate-upgrades", flags.allowRCUpgrades, "Show release candidate versions of Kubernetes as an upgrade alternative and allow upgrading to a release candidate versions of Kubernetes.")
|
||||
cmd.PersistentFlags().BoolVar(&flags.printConfig, "print-config", flags.printConfig, "Whether the configuration file that will be used in the upgrade should be printed or not.")
|
||||
cmd.PersistentFlags().BoolVar(&flags.skipPreFlight, "skip-preflight-checks", flags.skipPreFlight, "Skip preflight checks normally run before modifying the system")
|
||||
|
||||
cmd.AddCommand(NewCmdApply(flags))
|
||||
cmd.AddCommand(NewCmdPlan(flags))
|
||||
|
||||
return cmd
|
||||
}
|
||||
28
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/util/BUILD
generated
vendored
Normal file
28
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/util/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["cmdutil.go"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = ["//vendor/github.com/spf13/cobra:go_default_library"],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["cmdutil_test.go"],
|
||||
library = ":go_default_library",
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
57
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/util/cmdutil.go
generated
vendored
Normal file
57
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/util/cmdutil.go
generated
vendored
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
Copyright 2017 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 phases
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// SubCmdRunE returns a function that handles a case where a subcommand must be specified
|
||||
// Without this callback, if a user runs just the command without a subcommand,
|
||||
// or with an invalid subcommand, cobra will print usage information, but still exit cleanly.
|
||||
// We want to return an error code in these cases so that the
|
||||
// user knows that their command was invalid.
|
||||
func SubCmdRunE(name string) func(*cobra.Command, []string) error {
|
||||
return func(_ *cobra.Command, args []string) error {
|
||||
if len(args) < 1 {
|
||||
return fmt.Errorf("missing subcommand; %q is not meant to be run on its own", name)
|
||||
}
|
||||
|
||||
return fmt.Errorf("invalid subcommand: %q", args[0])
|
||||
}
|
||||
}
|
||||
|
||||
// ValidateExactArgNumber validates that the required top-level arguments are specified
|
||||
func ValidateExactArgNumber(args []string, supportedArgs []string) error {
|
||||
validArgs := 0
|
||||
// Disregard possible "" arguments; they are invalid
|
||||
for _, arg := range args {
|
||||
if len(arg) > 0 {
|
||||
validArgs++
|
||||
}
|
||||
}
|
||||
|
||||
if validArgs < len(supportedArgs) {
|
||||
return fmt.Errorf("missing one or more required arguments. Required arguments: %v", supportedArgs)
|
||||
}
|
||||
if validArgs > len(supportedArgs) {
|
||||
return fmt.Errorf("too many arguments, only %d argument(s) supported: %v", validArgs, supportedArgs)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
64
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/util/cmdutil_test.go
generated
vendored
Normal file
64
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/util/cmdutil_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
Copyright 2017 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 phases
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestValidateExactArgNumber(t *testing.T) {
|
||||
var tests = []struct {
|
||||
args, supportedArgs []string
|
||||
expectedErr bool
|
||||
}{
|
||||
{ // one arg given and one arg expected
|
||||
args: []string{"my-node-1234"},
|
||||
supportedArgs: []string{"node-name"},
|
||||
expectedErr: false,
|
||||
},
|
||||
{ // two args given and two args expected
|
||||
args: []string{"my-node-1234", "foo"},
|
||||
supportedArgs: []string{"node-name", "second-toplevel-arg"},
|
||||
expectedErr: false,
|
||||
},
|
||||
{ // too few supplied args
|
||||
args: []string{},
|
||||
supportedArgs: []string{"node-name"},
|
||||
expectedErr: true,
|
||||
},
|
||||
{ // too few non-empty args
|
||||
args: []string{""},
|
||||
supportedArgs: []string{"node-name"},
|
||||
expectedErr: true,
|
||||
},
|
||||
{ // too many args
|
||||
args: []string{"my-node-1234", "foo"},
|
||||
supportedArgs: []string{"node-name"},
|
||||
expectedErr: true,
|
||||
},
|
||||
}
|
||||
for _, rt := range tests {
|
||||
actual := ValidateExactArgNumber(rt.args, rt.supportedArgs)
|
||||
if (actual != nil) != rt.expectedErr {
|
||||
t.Errorf(
|
||||
"failed ValidateExactArgNumber:\n\texpected error: %t\n\t actual error: %t",
|
||||
rt.expectedErr,
|
||||
(actual != nil),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
80
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/version.go
generated
vendored
Normal file
80
vendor/k8s.io/kubernetes/cmd/kubeadm/app/cmd/version.go
generated
vendored
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
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 cmd
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
apimachineryversion "k8s.io/apimachinery/pkg/version"
|
||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||
"k8s.io/kubernetes/pkg/version"
|
||||
)
|
||||
|
||||
// Version provides the version information of kubeadm.
|
||||
type Version struct {
|
||||
ClientVersion *apimachineryversion.Info `json:"clientVersion"`
|
||||
}
|
||||
|
||||
func NewCmdVersion(out io.Writer) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "version",
|
||||
Short: i18n.T("Print the version of kubeadm"),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
err := RunVersion(out, cmd)
|
||||
kubeadmutil.CheckErr(err)
|
||||
},
|
||||
}
|
||||
cmd.Flags().StringP("output", "o", "", "output format, options available are yaml, json and short")
|
||||
return cmd
|
||||
}
|
||||
|
||||
func RunVersion(out io.Writer, cmd *cobra.Command) error {
|
||||
clientVersion := version.Get()
|
||||
v := Version{
|
||||
ClientVersion: &clientVersion,
|
||||
}
|
||||
|
||||
switch of := cmdutil.GetFlagString(cmd, "output"); of {
|
||||
case "":
|
||||
fmt.Fprintf(out, "kubeadm version: %#v\n", v.ClientVersion)
|
||||
case "short":
|
||||
fmt.Fprintf(out, "%s\n", v.ClientVersion.GitVersion)
|
||||
case "yaml":
|
||||
y, err := yaml.Marshal(&v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintln(out, string(y))
|
||||
case "json":
|
||||
y, err := json.MarshalIndent(&v, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintln(out, string(y))
|
||||
default:
|
||||
return fmt.Errorf("invalid output format: %s", of)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
36
vendor/k8s.io/kubernetes/cmd/kubeadm/app/constants/BUILD
generated
vendored
Normal file
36
vendor/k8s.io/kubernetes/cmd/kubeadm/app/constants/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["constants.go"],
|
||||
deps = [
|
||||
"//pkg/util/version:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["constants_test.go"],
|
||||
library = ":go_default_library",
|
||||
deps = ["//pkg/util/version:go_default_library"],
|
||||
)
|
||||
210
vendor/k8s.io/kubernetes/cmd/kubeadm/app/constants/constants.go
generated
vendored
Normal file
210
vendor/k8s.io/kubernetes/cmd/kubeadm/app/constants/constants.go
generated
vendored
Normal file
|
|
@ -0,0 +1,210 @@
|
|||
/*
|
||||
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 constants
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/kubernetes/pkg/util/version"
|
||||
)
|
||||
|
||||
// KubernetesDir is the directory kubernetes owns for storing various configuration files
|
||||
// This semi-constant MUST NOT be modified during runtime. It's a variable solely for use in unit testing.
|
||||
var KubernetesDir = "/etc/kubernetes"
|
||||
|
||||
const (
|
||||
ManifestsSubDirName = "manifests"
|
||||
TempDirForKubeadm = "/etc/kubernetes/tmp"
|
||||
|
||||
CACertAndKeyBaseName = "ca"
|
||||
CACertName = "ca.crt"
|
||||
CAKeyName = "ca.key"
|
||||
|
||||
APIServerCertAndKeyBaseName = "apiserver"
|
||||
APIServerCertName = "apiserver.crt"
|
||||
APIServerKeyName = "apiserver.key"
|
||||
APIServerCertCommonName = "kube-apiserver" //used as subject.commonname attribute (CN)
|
||||
|
||||
APIServerKubeletClientCertAndKeyBaseName = "apiserver-kubelet-client"
|
||||
APIServerKubeletClientCertName = "apiserver-kubelet-client.crt"
|
||||
APIServerKubeletClientKeyName = "apiserver-kubelet-client.key"
|
||||
APIServerKubeletClientCertCommonName = "kube-apiserver-kubelet-client" //used as subject.commonname attribute (CN)
|
||||
|
||||
ServiceAccountKeyBaseName = "sa"
|
||||
ServiceAccountPublicKeyName = "sa.pub"
|
||||
ServiceAccountPrivateKeyName = "sa.key"
|
||||
|
||||
FrontProxyCACertAndKeyBaseName = "front-proxy-ca"
|
||||
FrontProxyCACertName = "front-proxy-ca.crt"
|
||||
FrontProxyCAKeyName = "front-proxy-ca.key"
|
||||
|
||||
FrontProxyClientCertAndKeyBaseName = "front-proxy-client"
|
||||
FrontProxyClientCertName = "front-proxy-client.crt"
|
||||
FrontProxyClientKeyName = "front-proxy-client.key"
|
||||
FrontProxyClientCertCommonName = "front-proxy-client" //used as subject.commonname attribute (CN)
|
||||
|
||||
AdminKubeConfigFileName = "admin.conf"
|
||||
KubeletBootstrapKubeConfigFileName = "bootstrap-kubelet.conf"
|
||||
KubeletKubeConfigFileName = "kubelet.conf"
|
||||
ControllerManagerKubeConfigFileName = "controller-manager.conf"
|
||||
SchedulerKubeConfigFileName = "scheduler.conf"
|
||||
|
||||
// Some well-known users and groups in the core Kubernetes authorization system
|
||||
|
||||
ControllerManagerUser = "system:kube-controller-manager"
|
||||
SchedulerUser = "system:kube-scheduler"
|
||||
MastersGroup = "system:masters"
|
||||
NodesGroup = "system:nodes"
|
||||
NodesClusterRoleBinding = "system:node"
|
||||
|
||||
// APICallRetryInterval defines how long kubeadm should wait before retrying a failed API operation
|
||||
APICallRetryInterval = 500 * time.Millisecond
|
||||
// DiscoveryRetryInterval specifies how long kubeadm should wait before retrying to connect to the master when doing discovery
|
||||
DiscoveryRetryInterval = 5 * time.Second
|
||||
// MarkMasterTimeout specifies how long kubeadm should wait for applying the label and taint on the master before timing out
|
||||
MarkMasterTimeout = 2 * time.Minute
|
||||
|
||||
// Minimum amount of nodes the Service subnet should allow.
|
||||
// We need at least ten, because the DNS service is always at the tenth cluster clusterIP
|
||||
MinimumAddressesInServiceSubnet = 10
|
||||
|
||||
// DefaultTokenDuration specifies the default amount of time that a bootstrap token will be valid
|
||||
// Default behaviour is 24 hours
|
||||
DefaultTokenDuration = 24 * time.Hour
|
||||
|
||||
// LabelNodeRoleMaster specifies that a node is a master
|
||||
// It's copied over to kubeadm until it's merged in core: https://github.com/kubernetes/kubernetes/pull/39112
|
||||
LabelNodeRoleMaster = "node-role.kubernetes.io/master"
|
||||
|
||||
// MasterConfigurationConfigMap specifies in what ConfigMap in the kube-system namespace the `kubeadm init` configuration should be stored
|
||||
MasterConfigurationConfigMap = "kubeadm-config"
|
||||
|
||||
// MasterConfigurationConfigMapKey specifies in what ConfigMap key the master configuration should be stored
|
||||
MasterConfigurationConfigMapKey = "MasterConfiguration"
|
||||
|
||||
// MinExternalEtcdVersion indicates minimum external etcd version which kubeadm supports
|
||||
MinExternalEtcdVersion = "3.0.14"
|
||||
|
||||
// DefaultEtcdVersion indicates the default etcd version that kubeadm uses
|
||||
DefaultEtcdVersion = "3.0.17"
|
||||
|
||||
Etcd = "etcd"
|
||||
KubeAPIServer = "kube-apiserver"
|
||||
KubeControllerManager = "kube-controller-manager"
|
||||
KubeScheduler = "kube-scheduler"
|
||||
KubeProxy = "kube-proxy"
|
||||
|
||||
// SelfHostingPrefix describes the prefix workloads that are self-hosted by kubeadm has
|
||||
SelfHostingPrefix = "self-hosted-"
|
||||
|
||||
// KubeCertificatesVolumeName specifies the name for the Volume that is used for injecting certificates to control plane components (can be both a hostPath volume or a projected, all-in-one volume)
|
||||
KubeCertificatesVolumeName = "k8s-certs"
|
||||
|
||||
// KubeConfigVolumeName specifies the name for the Volume that is used for injecting the kubeconfig to talk securely to the api server for a control plane component if applicable
|
||||
KubeConfigVolumeName = "kubeconfig"
|
||||
|
||||
// V17NodeBootstrapTokenAuthGroup specifies which group a Node Bootstrap Token should be authenticated in, in v1.7
|
||||
V17NodeBootstrapTokenAuthGroup = "system:bootstrappers"
|
||||
|
||||
// V18NodeBootstrapTokenAuthGroup specifies which group a Node Bootstrap Token should be authenticated in, in v1.8
|
||||
V18NodeBootstrapTokenAuthGroup = "system:bootstrappers:kubeadm:default-node-token"
|
||||
|
||||
// DefaultCIImageRepository points to image registry where CI uploads images from ci-cross build job
|
||||
DefaultCIImageRepository = "gcr.io/kubernetes-ci-images"
|
||||
)
|
||||
|
||||
var (
|
||||
|
||||
// MasterTaint is the taint to apply on the PodSpec for being able to run that Pod on the master
|
||||
MasterTaint = v1.Taint{
|
||||
Key: LabelNodeRoleMaster,
|
||||
Effect: v1.TaintEffectNoSchedule,
|
||||
}
|
||||
|
||||
// MasterToleration is the toleration to apply on the PodSpec for being able to run that Pod on the master
|
||||
MasterToleration = v1.Toleration{
|
||||
Key: LabelNodeRoleMaster,
|
||||
Effect: v1.TaintEffectNoSchedule,
|
||||
}
|
||||
|
||||
AuthorizationPolicyPath = filepath.Join(KubernetesDir, "abac_policy.json")
|
||||
AuthorizationWebhookConfigPath = filepath.Join(KubernetesDir, "webhook_authz.conf")
|
||||
|
||||
// DefaultTokenUsages specifies the default functions a token will get
|
||||
DefaultTokenUsages = []string{"signing", "authentication"}
|
||||
|
||||
// MasterComponents defines the master component names
|
||||
MasterComponents = []string{KubeAPIServer, KubeControllerManager, KubeScheduler}
|
||||
|
||||
// MinimumControlPlaneVersion specifies the minimum control plane version kubeadm can deploy
|
||||
MinimumControlPlaneVersion = version.MustParseSemantic("v1.7.0")
|
||||
|
||||
// MinimumCSRAutoApprovalClusterRolesVersion defines whether kubeadm can rely on the built-in CSR approval ClusterRole or not (note, the binding is always created by kubeadm!)
|
||||
// TODO: Remove this when the v1.9 cycle starts and we bump the minimum supported version to v1.8.0
|
||||
MinimumCSRAutoApprovalClusterRolesVersion = version.MustParseSemantic("v1.8.0-alpha.3")
|
||||
|
||||
// UseEnableBootstrapTokenAuthFlagVersion defines the first version where the API server supports the --enable-bootstrap-token-auth flag instead of the old and deprecated flag.
|
||||
// TODO: Remove this when the v1.9 cycle starts and we bump the minimum supported version to v1.8.0
|
||||
UseEnableBootstrapTokenAuthFlagVersion = version.MustParseSemantic("v1.8.0-beta.0")
|
||||
)
|
||||
|
||||
// GetStaticPodDirectory returns the location on the disk where the Static Pod should be present
|
||||
func GetStaticPodDirectory() string {
|
||||
return filepath.Join(KubernetesDir, ManifestsSubDirName)
|
||||
}
|
||||
|
||||
// GetStaticPodFilepath returns the location on the disk where the Static Pod should be present
|
||||
func GetStaticPodFilepath(componentName, manifestsDir string) string {
|
||||
return filepath.Join(manifestsDir, componentName+".yaml")
|
||||
}
|
||||
|
||||
// GetAdminKubeConfigPath returns the location on the disk where admin kubeconfig is located by default
|
||||
func GetAdminKubeConfigPath() string {
|
||||
return filepath.Join(KubernetesDir, AdminKubeConfigFileName)
|
||||
}
|
||||
|
||||
// AddSelfHostedPrefix adds the self-hosted- prefix to the component name
|
||||
func AddSelfHostedPrefix(componentName string) string {
|
||||
return fmt.Sprintf("%s%s", SelfHostingPrefix, componentName)
|
||||
}
|
||||
|
||||
// CreateTempDirForKubeadm is a function that creates a temporary directory under /etc/kubernetes/tmp (not using /tmp as that would potentially be dangerous)
|
||||
func CreateTempDirForKubeadm(dirName string) (string, error) {
|
||||
// creates target folder if not already exists
|
||||
if err := os.MkdirAll(TempDirForKubeadm, 0700); err != nil {
|
||||
return "", fmt.Errorf("failed to create directory %q: %v", TempDirForKubeadm, err)
|
||||
}
|
||||
|
||||
tempDir, err := ioutil.TempDir(TempDirForKubeadm, dirName)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("couldn't create a temporary directory: %v", err)
|
||||
}
|
||||
return tempDir, nil
|
||||
}
|
||||
|
||||
// GetNodeBootstrapTokenAuthGroup gets the bootstrap token auth group conditionally based on version
|
||||
func GetNodeBootstrapTokenAuthGroup(k8sVersion *version.Version) string {
|
||||
if k8sVersion.AtLeast(UseEnableBootstrapTokenAuthFlagVersion) {
|
||||
return V18NodeBootstrapTokenAuthGroup
|
||||
}
|
||||
return V17NodeBootstrapTokenAuthGroup
|
||||
}
|
||||
159
vendor/k8s.io/kubernetes/cmd/kubeadm/app/constants/constants_test.go
generated
vendored
Normal file
159
vendor/k8s.io/kubernetes/cmd/kubeadm/app/constants/constants_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
Copyright 2017 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 constants
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/util/version"
|
||||
)
|
||||
|
||||
func TestGetStaticPodDirectory(t *testing.T) {
|
||||
expected := "/etc/kubernetes/manifests"
|
||||
actual := GetStaticPodDirectory()
|
||||
|
||||
if actual != expected {
|
||||
t.Errorf(
|
||||
"failed GetStaticPodDirectory:\n\texpected: %s\n\t actual: %s",
|
||||
expected,
|
||||
actual,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAdminKubeConfigPath(t *testing.T) {
|
||||
expected := "/etc/kubernetes/admin.conf"
|
||||
actual := GetAdminKubeConfigPath()
|
||||
|
||||
if actual != expected {
|
||||
t.Errorf(
|
||||
"failed GetAdminKubeConfigPath:\n\texpected: %s\n\t actual: %s",
|
||||
expected,
|
||||
actual,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetStaticPodFilepath(t *testing.T) {
|
||||
var tests = []struct {
|
||||
componentName, manifestsDir, expected string
|
||||
}{
|
||||
{
|
||||
componentName: "kube-apiserver",
|
||||
manifestsDir: "/etc/kubernetes/manifests",
|
||||
expected: "/etc/kubernetes/manifests/kube-apiserver.yaml",
|
||||
},
|
||||
{
|
||||
componentName: "kube-controller-manager",
|
||||
manifestsDir: "/etc/kubernetes/manifests/",
|
||||
expected: "/etc/kubernetes/manifests/kube-controller-manager.yaml",
|
||||
},
|
||||
{
|
||||
componentName: "foo",
|
||||
manifestsDir: "/etc/bar/",
|
||||
expected: "/etc/bar/foo.yaml",
|
||||
},
|
||||
}
|
||||
for _, rt := range tests {
|
||||
actual := GetStaticPodFilepath(rt.componentName, rt.manifestsDir)
|
||||
if actual != rt.expected {
|
||||
t.Errorf(
|
||||
"failed GetStaticPodFilepath:\n\texpected: %s\n\t actual: %s",
|
||||
rt.expected,
|
||||
actual,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestAddSelfHostedPrefix(t *testing.T) {
|
||||
var tests = []struct {
|
||||
componentName, expected string
|
||||
}{
|
||||
{
|
||||
componentName: "kube-apiserver",
|
||||
expected: "self-hosted-kube-apiserver",
|
||||
},
|
||||
{
|
||||
componentName: "kube-controller-manager",
|
||||
expected: "self-hosted-kube-controller-manager",
|
||||
},
|
||||
{
|
||||
componentName: "kube-scheduler",
|
||||
expected: "self-hosted-kube-scheduler",
|
||||
},
|
||||
{
|
||||
componentName: "foo",
|
||||
expected: "self-hosted-foo",
|
||||
},
|
||||
}
|
||||
for _, rt := range tests {
|
||||
actual := AddSelfHostedPrefix(rt.componentName)
|
||||
if actual != rt.expected {
|
||||
t.Errorf(
|
||||
"failed AddSelfHostedPrefix:\n\texpected: %s\n\t actual: %s",
|
||||
rt.expected,
|
||||
actual,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetNodeBootstrapTokenAuthGroup(t *testing.T) {
|
||||
var tests = []struct {
|
||||
k8sVersion, expected string
|
||||
}{
|
||||
{
|
||||
k8sVersion: "v1.7.0",
|
||||
expected: "system:bootstrappers",
|
||||
},
|
||||
{
|
||||
k8sVersion: "v1.7.8",
|
||||
expected: "system:bootstrappers",
|
||||
},
|
||||
{
|
||||
k8sVersion: "v1.8.0-alpha.3",
|
||||
expected: "system:bootstrappers",
|
||||
},
|
||||
{
|
||||
k8sVersion: "v1.8.0-beta.0",
|
||||
expected: "system:bootstrappers:kubeadm:default-node-token",
|
||||
},
|
||||
{
|
||||
k8sVersion: "v1.8.0-rc.1",
|
||||
expected: "system:bootstrappers:kubeadm:default-node-token",
|
||||
},
|
||||
{
|
||||
k8sVersion: "v1.8.0",
|
||||
expected: "system:bootstrappers:kubeadm:default-node-token",
|
||||
},
|
||||
{
|
||||
k8sVersion: "v1.8.9",
|
||||
expected: "system:bootstrappers:kubeadm:default-node-token",
|
||||
},
|
||||
}
|
||||
for _, rt := range tests {
|
||||
actual := GetNodeBootstrapTokenAuthGroup(version.MustParseSemantic(rt.k8sVersion))
|
||||
if actual != rt.expected {
|
||||
t.Errorf(
|
||||
"failed GetNodeBootstrapTokenAuthGroup:\n\texpected: %s\n\t actual: %s",
|
||||
rt.expected,
|
||||
actual,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
45
vendor/k8s.io/kubernetes/cmd/kubeadm/app/discovery/BUILD
generated
vendored
Normal file
45
vendor/k8s.io/kubernetes/cmd/kubeadm/app/discovery/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["discovery.go"],
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||
"//cmd/kubeadm/app/discovery/file:go_default_library",
|
||||
"//cmd/kubeadm/app/discovery/https:go_default_library",
|
||||
"//cmd/kubeadm/app/discovery/token:go_default_library",
|
||||
"//cmd/kubeadm/app/util/kubeconfig:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/clientcmd/api:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["discovery_test.go"],
|
||||
library = ":go_default_library",
|
||||
deps = ["//cmd/kubeadm/app/apis/kubeadm:go_default_library"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//cmd/kubeadm/app/discovery/file:all-srcs",
|
||||
"//cmd/kubeadm/app/discovery/https:all-srcs",
|
||||
"//cmd/kubeadm/app/discovery/token:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
71
vendor/k8s.io/kubernetes/cmd/kubeadm/app/discovery/discovery.go
generated
vendored
Normal file
71
vendor/k8s.io/kubernetes/cmd/kubeadm/app/discovery/discovery.go
generated
vendored
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
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 discovery
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/discovery/file"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/discovery/https"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/discovery/token"
|
||||
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
|
||||
)
|
||||
|
||||
const TokenUser = "tls-bootstrap-token-user"
|
||||
|
||||
// For returns a KubeConfig object that can be used for doing the TLS Bootstrap with the right credentials
|
||||
// Also, before returning anything, it makes sure it can trust the API Server
|
||||
func For(cfg *kubeadmapi.NodeConfiguration) (*clientcmdapi.Config, error) {
|
||||
// TODO: Print summary info about the CA certificate, along with the the checksum signature
|
||||
// we also need an ability for the user to configure the client to validate received CA cert against a checksum
|
||||
clusterinfo, err := GetValidatedClusterInfoObject(cfg)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("couldn't validate the identity of the API Server: %v", err)
|
||||
}
|
||||
|
||||
return kubeconfigutil.CreateWithToken(
|
||||
clusterinfo.Server,
|
||||
"kubernetes",
|
||||
TokenUser,
|
||||
clusterinfo.CertificateAuthorityData,
|
||||
cfg.TLSBootstrapToken,
|
||||
), nil
|
||||
}
|
||||
|
||||
// GetValidatedClusterInfoObject returns a validated Cluster object that specifies where the cluster is and the CA cert to trust
|
||||
func GetValidatedClusterInfoObject(cfg *kubeadmapi.NodeConfiguration) (*clientcmdapi.Cluster, error) {
|
||||
switch {
|
||||
case len(cfg.DiscoveryFile) != 0:
|
||||
if isHTTPSURL(cfg.DiscoveryFile) {
|
||||
return https.RetrieveValidatedClusterInfo(cfg.DiscoveryFile)
|
||||
}
|
||||
return file.RetrieveValidatedClusterInfo(cfg.DiscoveryFile)
|
||||
case len(cfg.DiscoveryToken) != 0:
|
||||
return token.RetrieveValidatedClusterInfo(cfg.DiscoveryToken, cfg.DiscoveryTokenAPIServers, cfg.DiscoveryTokenCACertHashes)
|
||||
default:
|
||||
return nil, fmt.Errorf("couldn't find a valid discovery configuration.")
|
||||
}
|
||||
}
|
||||
|
||||
// isHTTPSURL checks whether the string is parsable as an URL and whether the Scheme is https
|
||||
func isHTTPSURL(s string) bool {
|
||||
u, err := url.Parse(s)
|
||||
return err == nil && u.Scheme == "https"
|
||||
}
|
||||
66
vendor/k8s.io/kubernetes/cmd/kubeadm/app/discovery/discovery_test.go
generated
vendored
Normal file
66
vendor/k8s.io/kubernetes/cmd/kubeadm/app/discovery/discovery_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
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 discovery
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
)
|
||||
|
||||
func TestFor(t *testing.T) {
|
||||
tests := []struct {
|
||||
d kubeadm.NodeConfiguration
|
||||
expect bool
|
||||
}{
|
||||
{d: kubeadm.NodeConfiguration{}, expect: false},
|
||||
{
|
||||
d: kubeadm.NodeConfiguration{
|
||||
DiscoveryFile: "notnil",
|
||||
},
|
||||
expect: false,
|
||||
},
|
||||
{
|
||||
d: kubeadm.NodeConfiguration{
|
||||
DiscoveryFile: "https://localhost",
|
||||
},
|
||||
expect: false,
|
||||
},
|
||||
{
|
||||
d: kubeadm.NodeConfiguration{
|
||||
DiscoveryFile: "notnil",
|
||||
},
|
||||
expect: false,
|
||||
},
|
||||
{
|
||||
d: kubeadm.NodeConfiguration{
|
||||
DiscoveryToken: "foo.bar@foobar",
|
||||
},
|
||||
expect: false,
|
||||
},
|
||||
}
|
||||
for _, rt := range tests {
|
||||
_, actual := For(&rt.d)
|
||||
if (actual == nil) != rt.expect {
|
||||
t.Errorf(
|
||||
"failed For:\n\texpected: %t\n\t actual: %t",
|
||||
rt.expect,
|
||||
(actual == nil),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
35
vendor/k8s.io/kubernetes/cmd/kubeadm/app/discovery/file/BUILD
generated
vendored
Normal file
35
vendor/k8s.io/kubernetes/cmd/kubeadm/app/discovery/file/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["file.go"],
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/constants:go_default_library",
|
||||
"//cmd/kubeadm/app/util/kubeconfig:go_default_library",
|
||||
"//pkg/bootstrap/api:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/clientcmd:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/clientcmd/api:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
130
vendor/k8s.io/kubernetes/cmd/kubeadm/app/discovery/file/file.go
generated
vendored
Normal file
130
vendor/k8s.io/kubernetes/cmd/kubeadm/app/discovery/file/file.go
generated
vendored
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
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 file
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
|
||||
bootstrapapi "k8s.io/kubernetes/pkg/bootstrap/api"
|
||||
)
|
||||
|
||||
// RetrieveValidatedClusterInfo connects to the API Server and makes sure it can talk
|
||||
// securely to the API Server using the provided CA cert and
|
||||
// optionally refreshes the cluster-info information from the cluster-info ConfigMap
|
||||
func RetrieveValidatedClusterInfo(filepath string) (*clientcmdapi.Cluster, error) {
|
||||
clusterinfo, err := clientcmd.LoadFromFile(filepath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ValidateClusterInfo(clusterinfo)
|
||||
}
|
||||
|
||||
// ValidateClusterInfo connects to the API Server and makes sure it can talk
|
||||
// securely to the API Server using the provided CA cert and
|
||||
// optionally refreshes the cluster-info information from the cluster-info ConfigMap
|
||||
func ValidateClusterInfo(clusterinfo *clientcmdapi.Config) (*clientcmdapi.Cluster, error) {
|
||||
err := validateClusterInfoKubeConfig(clusterinfo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// This is the cluster object we've got from the cluster-info KubeConfig file
|
||||
defaultCluster := kubeconfigutil.GetClusterFromKubeConfig(clusterinfo)
|
||||
|
||||
// Create a new kubeconfig object from the given, just copy over the server and the CA cert
|
||||
// We do this in order to not pick up other possible misconfigurations in the clusterinfo file
|
||||
configFromClusterInfo := kubeconfigutil.CreateBasic(
|
||||
defaultCluster.Server,
|
||||
"kubernetes",
|
||||
"", // no user provided
|
||||
defaultCluster.CertificateAuthorityData,
|
||||
)
|
||||
|
||||
client, err := kubeconfigutil.KubeConfigToClientSet(configFromClusterInfo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fmt.Printf("[discovery] Created cluster-info discovery client, requesting info from %q\n", defaultCluster.Server)
|
||||
|
||||
var clusterinfoCM *v1.ConfigMap
|
||||
wait.PollInfinite(constants.DiscoveryRetryInterval, func() (bool, error) {
|
||||
var err error
|
||||
clusterinfoCM, err = client.CoreV1().ConfigMaps(metav1.NamespacePublic).Get(bootstrapapi.ConfigMapClusterInfo, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
if apierrors.IsForbidden(err) {
|
||||
// If the request is unauthorized, the cluster admin has not granted access to the cluster info configmap for unauthenicated users
|
||||
// In that case, trust the cluster admin and do not refresh the cluster-info credentials
|
||||
fmt.Printf("[discovery] Could not access the %s ConfigMap for refreshing the cluster-info information, but the TLS cert is valid so proceeding...\n", bootstrapapi.ConfigMapClusterInfo)
|
||||
return true, nil
|
||||
} else {
|
||||
fmt.Printf("[discovery] Failed to validate the API Server's identity, will try again: [%v]\n", err)
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
return true, nil
|
||||
})
|
||||
|
||||
// If we couldn't fetch the cluster-info ConfigMap, just return the cluster-info object the user provided
|
||||
if clusterinfoCM == nil {
|
||||
return defaultCluster, nil
|
||||
}
|
||||
|
||||
// We somehow got hold of the ConfigMap, try to read some data from it. If we can't, fallback on the user-provided file
|
||||
refreshedBaseKubeConfig, err := tryParseClusterInfoFromConfigMap(clusterinfoCM)
|
||||
if err != nil {
|
||||
fmt.Printf("[discovery] The %s ConfigMap isn't set up properly (%v), but the TLS cert is valid so proceeding...\n", bootstrapapi.ConfigMapClusterInfo, err)
|
||||
return defaultCluster, nil
|
||||
}
|
||||
|
||||
fmt.Println("[discovery] Synced cluster-info information from the API Server so we have got the latest information")
|
||||
// In an HA world in the future, this will make more sense, because now we've got new information, possibly about new API Servers to talk to
|
||||
return kubeconfigutil.GetClusterFromKubeConfig(refreshedBaseKubeConfig), nil
|
||||
}
|
||||
|
||||
// tryParseClusterInfoFromConfigMap tries to parse a kubeconfig file from a ConfigMap key
|
||||
func tryParseClusterInfoFromConfigMap(cm *v1.ConfigMap) (*clientcmdapi.Config, error) {
|
||||
kubeConfigString, ok := cm.Data[bootstrapapi.KubeConfigKey]
|
||||
if !ok || len(kubeConfigString) == 0 {
|
||||
return nil, fmt.Errorf("no %s key in ConfigMap", bootstrapapi.KubeConfigKey)
|
||||
}
|
||||
parsedKubeConfig, err := clientcmd.Load([]byte(kubeConfigString))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("couldn't parse the kubeconfig file in the %s ConfigMap: %v", bootstrapapi.ConfigMapClusterInfo, err)
|
||||
}
|
||||
return parsedKubeConfig, nil
|
||||
}
|
||||
|
||||
// validateClusterInfoKubeConfig makes sure the user-provided cluster-info KubeConfig file is valid
|
||||
func validateClusterInfoKubeConfig(clusterinfo *clientcmdapi.Config) error {
|
||||
if len(clusterinfo.Clusters) < 1 {
|
||||
return fmt.Errorf("the provided cluster-info KubeConfig file must have at least one Cluster defined")
|
||||
}
|
||||
defaultCluster := kubeconfigutil.GetClusterFromKubeConfig(clusterinfo)
|
||||
if defaultCluster == nil {
|
||||
return fmt.Errorf("the provided cluster-info KubeConfig file must have an unnamed Cluster or a CurrentContext that specifies a non-nil Cluster")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
29
vendor/k8s.io/kubernetes/cmd/kubeadm/app/discovery/https/BUILD
generated
vendored
Normal file
29
vendor/k8s.io/kubernetes/cmd/kubeadm/app/discovery/https/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["https.go"],
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/discovery/file:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/clientcmd:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/clientcmd/api:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
48
vendor/k8s.io/kubernetes/cmd/kubeadm/app/discovery/https/https.go
generated
vendored
Normal file
48
vendor/k8s.io/kubernetes/cmd/kubeadm/app/discovery/https/https.go
generated
vendored
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
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 https
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/discovery/file"
|
||||
)
|
||||
|
||||
// RetrieveValidatedClusterInfo connects to the API Server and makes sure it can talk
|
||||
// securely to the API Server using the provided CA cert and
|
||||
// optionally refreshes the cluster-info information from the cluster-info ConfigMap
|
||||
func RetrieveValidatedClusterInfo(httpsURL string) (*clientcmdapi.Cluster, error) {
|
||||
response, err := http.Get(httpsURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer response.Body.Close()
|
||||
|
||||
kubeconfig, err := ioutil.ReadAll(response.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
clusterinfo, err := clientcmd.Load(kubeconfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return file.ValidateClusterInfo(clusterinfo)
|
||||
}
|
||||
48
vendor/k8s.io/kubernetes/cmd/kubeadm/app/discovery/token/BUILD
generated
vendored
Normal file
48
vendor/k8s.io/kubernetes/cmd/kubeadm/app/discovery/token/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["token.go"],
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/constants:go_default_library",
|
||||
"//cmd/kubeadm/app/util/kubeconfig:go_default_library",
|
||||
"//cmd/kubeadm/app/util/pubkeypin:go_default_library",
|
||||
"//cmd/kubeadm/app/util/token:go_default_library",
|
||||
"//pkg/bootstrap/api:go_default_library",
|
||||
"//pkg/controller/bootstrap:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/clientcmd:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/clientcmd/api:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["token_test.go"],
|
||||
library = ":go_default_library",
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/util/kubeconfig:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/clientcmd/api:go_default_library",
|
||||
],
|
||||
)
|
||||
221
vendor/k8s.io/kubernetes/cmd/kubeadm/app/discovery/token/token.go
generated
vendored
Normal file
221
vendor/k8s.io/kubernetes/cmd/kubeadm/app/discovery/token/token.go
generated
vendored
Normal file
|
|
@ -0,0 +1,221 @@
|
|||
/*
|
||||
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 token
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/util/pubkeypin"
|
||||
tokenutil "k8s.io/kubernetes/cmd/kubeadm/app/util/token"
|
||||
bootstrapapi "k8s.io/kubernetes/pkg/bootstrap/api"
|
||||
"k8s.io/kubernetes/pkg/controller/bootstrap"
|
||||
)
|
||||
|
||||
const BootstrapUser = "token-bootstrap-client"
|
||||
|
||||
// RetrieveValidatedClusterInfo connects to the API Server and tries to fetch the cluster-info ConfigMap
|
||||
// It then makes sure it can trust the API Server by looking at the JWS-signed tokens and (if rootCAPubKeys is not empty)
|
||||
// validating the cluster CA against a set of pinned public keys
|
||||
func RetrieveValidatedClusterInfo(discoveryToken string, tokenAPIServers, rootCAPubKeys []string) (*clientcmdapi.Cluster, error) {
|
||||
tokenId, tokenSecret, err := tokenutil.ParseToken(discoveryToken)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Load the cfg.DiscoveryTokenCACertHashes into a pubkeypin.Set
|
||||
pubKeyPins := pubkeypin.NewSet()
|
||||
err = pubKeyPins.Allow(rootCAPubKeys...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// The function below runs for every endpoint, and all endpoints races with each other.
|
||||
// The endpoint that wins the race and completes the task first gets its kubeconfig returned below
|
||||
baseKubeConfig := runForEndpointsAndReturnFirst(tokenAPIServers, func(endpoint string) (*clientcmdapi.Config, error) {
|
||||
|
||||
insecureBootstrapConfig := buildInsecureBootstrapKubeConfig(endpoint)
|
||||
clusterName := insecureBootstrapConfig.Contexts[insecureBootstrapConfig.CurrentContext].Cluster
|
||||
|
||||
insecureClient, err := kubeconfigutil.KubeConfigToClientSet(insecureBootstrapConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fmt.Printf("[discovery] Created cluster-info discovery client, requesting info from %q\n", insecureBootstrapConfig.Clusters[clusterName].Server)
|
||||
|
||||
// Make an initial insecure connection to get the cluster-info ConfigMap
|
||||
var insecureClusterInfo *v1.ConfigMap
|
||||
wait.PollImmediateInfinite(constants.DiscoveryRetryInterval, func() (bool, error) {
|
||||
var err error
|
||||
insecureClusterInfo, err = insecureClient.CoreV1().ConfigMaps(metav1.NamespacePublic).Get(bootstrapapi.ConfigMapClusterInfo, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
fmt.Printf("[discovery] Failed to request cluster info, will try again: [%s]\n", err)
|
||||
return false, nil
|
||||
}
|
||||
return true, nil
|
||||
})
|
||||
|
||||
// Validate the MAC on the kubeconfig from the ConfigMap and load it
|
||||
insecureKubeconfigString, ok := insecureClusterInfo.Data[bootstrapapi.KubeConfigKey]
|
||||
if !ok || len(insecureKubeconfigString) == 0 {
|
||||
return nil, fmt.Errorf("there is no %s key in the %s ConfigMap. This API Server isn't set up for token bootstrapping, can't connect", bootstrapapi.KubeConfigKey, bootstrapapi.ConfigMapClusterInfo)
|
||||
}
|
||||
detachedJWSToken, ok := insecureClusterInfo.Data[bootstrapapi.JWSSignatureKeyPrefix+tokenId]
|
||||
if !ok || len(detachedJWSToken) == 0 {
|
||||
return nil, fmt.Errorf("there is no JWS signed token in the %s ConfigMap. This token id %q is invalid for this cluster, can't connect", bootstrapapi.ConfigMapClusterInfo, tokenId)
|
||||
}
|
||||
if !bootstrap.DetachedTokenIsValid(detachedJWSToken, insecureKubeconfigString, tokenId, tokenSecret) {
|
||||
return nil, fmt.Errorf("failed to verify JWS signature of received cluster info object, can't trust this API Server")
|
||||
}
|
||||
insecureKubeconfigBytes := []byte(insecureKubeconfigString)
|
||||
insecureConfig, err := clientcmd.Load(insecureKubeconfigBytes)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("couldn't parse the kubeconfig file in the %s configmap: %v", bootstrapapi.ConfigMapClusterInfo, err)
|
||||
}
|
||||
|
||||
// If no TLS root CA pinning was specified, we're done
|
||||
if pubKeyPins.Empty() {
|
||||
fmt.Printf("[discovery] Cluster info signature and contents are valid and no TLS pinning was specified, will use API Server %q\n", endpoint)
|
||||
return insecureConfig, nil
|
||||
}
|
||||
|
||||
// Load the cluster CA from the Config
|
||||
if len(insecureConfig.Clusters) != 1 {
|
||||
return nil, fmt.Errorf("expected the kubeconfig file in the %s configmap to have a single cluster, but it had %d", bootstrapapi.ConfigMapClusterInfo, len(insecureConfig.Clusters))
|
||||
}
|
||||
var clusterCABytes []byte
|
||||
for _, cluster := range insecureConfig.Clusters {
|
||||
clusterCABytes = cluster.CertificateAuthorityData
|
||||
}
|
||||
clusterCA, err := parsePEMCert(clusterCABytes)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse cluster CA from the %s configmap: %v", bootstrapapi.ConfigMapClusterInfo, err)
|
||||
|
||||
}
|
||||
|
||||
// Validate the cluster CA public key against the pinned set
|
||||
err = pubKeyPins.Check(clusterCA)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cluster CA found in %s configmap is invalid: %v", bootstrapapi.ConfigMapClusterInfo, err)
|
||||
}
|
||||
|
||||
// Now that we know the proported cluster CA, connect back a second time validating with that CA
|
||||
secureBootstrapConfig := buildSecureBootstrapKubeConfig(endpoint, clusterCABytes)
|
||||
secureClient, err := kubeconfigutil.KubeConfigToClientSet(secureBootstrapConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fmt.Printf("[discovery] Requesting info from %q again to validate TLS against the pinned public key\n", insecureBootstrapConfig.Clusters[clusterName].Server)
|
||||
var secureClusterInfo *v1.ConfigMap
|
||||
wait.PollImmediateInfinite(constants.DiscoveryRetryInterval, func() (bool, error) {
|
||||
var err error
|
||||
secureClusterInfo, err = secureClient.CoreV1().ConfigMaps(metav1.NamespacePublic).Get(bootstrapapi.ConfigMapClusterInfo, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
fmt.Printf("[discovery] Failed to request cluster info, will try again: [%s]\n", err)
|
||||
return false, nil
|
||||
}
|
||||
return true, nil
|
||||
})
|
||||
|
||||
// Pull the kubeconfig from the securely-obtained ConfigMap and validate that it's the same as what we found the first time
|
||||
secureKubeconfigBytes := []byte(secureClusterInfo.Data[bootstrapapi.KubeConfigKey])
|
||||
if !bytes.Equal(secureKubeconfigBytes, insecureKubeconfigBytes) {
|
||||
return nil, fmt.Errorf("the second kubeconfig from the %s configmap (using validated TLS) was different from the first", bootstrapapi.ConfigMapClusterInfo)
|
||||
}
|
||||
|
||||
secureKubeconfig, err := clientcmd.Load(secureKubeconfigBytes)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("couldn't parse the kubeconfig file in the %s configmap: %v", bootstrapapi.ConfigMapClusterInfo, err)
|
||||
}
|
||||
|
||||
fmt.Printf("[discovery] Cluster info signature and contents are valid and TLS certificate validates against pinned roots, will use API Server %q\n", endpoint)
|
||||
return secureKubeconfig, nil
|
||||
})
|
||||
|
||||
return kubeconfigutil.GetClusterFromKubeConfig(baseKubeConfig), nil
|
||||
}
|
||||
|
||||
// buildInsecureBootstrapKubeConfig makes a KubeConfig object that connects insecurely to the API Server for bootstrapping purposes
|
||||
func buildInsecureBootstrapKubeConfig(endpoint string) *clientcmdapi.Config {
|
||||
masterEndpoint := fmt.Sprintf("https://%s", endpoint)
|
||||
clusterName := "kubernetes"
|
||||
bootstrapConfig := kubeconfigutil.CreateBasic(masterEndpoint, clusterName, BootstrapUser, []byte{})
|
||||
bootstrapConfig.Clusters[clusterName].InsecureSkipTLSVerify = true
|
||||
return bootstrapConfig
|
||||
}
|
||||
|
||||
// buildSecureBootstrapKubeConfig makes a KubeConfig object that connects securely to the API Server for bootstrapping purposes (validating with the specified CA)
|
||||
func buildSecureBootstrapKubeConfig(endpoint string, caCert []byte) *clientcmdapi.Config {
|
||||
masterEndpoint := fmt.Sprintf("https://%s", endpoint)
|
||||
bootstrapConfig := kubeconfigutil.CreateBasic(masterEndpoint, "kubernetes", BootstrapUser, caCert)
|
||||
return bootstrapConfig
|
||||
}
|
||||
|
||||
// runForEndpointsAndReturnFirst loops the endpoints slice and let's the endpoints race for connecting to the master
|
||||
func runForEndpointsAndReturnFirst(endpoints []string, fetchKubeConfigFunc func(string) (*clientcmdapi.Config, error)) *clientcmdapi.Config {
|
||||
stopChan := make(chan struct{})
|
||||
var resultingKubeConfig *clientcmdapi.Config
|
||||
var once sync.Once
|
||||
var wg sync.WaitGroup
|
||||
for _, endpoint := range endpoints {
|
||||
wg.Add(1)
|
||||
go func(apiEndpoint string) {
|
||||
defer wg.Done()
|
||||
wait.Until(func() {
|
||||
fmt.Printf("[discovery] Trying to connect to API Server %q\n", apiEndpoint)
|
||||
cfg, err := fetchKubeConfigFunc(apiEndpoint)
|
||||
if err != nil {
|
||||
fmt.Printf("[discovery] Failed to connect to API Server %q: %v\n", apiEndpoint, err)
|
||||
return
|
||||
}
|
||||
fmt.Printf("[discovery] Successfully established connection with API Server %q\n", apiEndpoint)
|
||||
|
||||
// connection established, stop all wait threads
|
||||
once.Do(func() {
|
||||
close(stopChan)
|
||||
resultingKubeConfig = cfg
|
||||
})
|
||||
}, constants.DiscoveryRetryInterval, stopChan)
|
||||
}(endpoint)
|
||||
}
|
||||
wg.Wait()
|
||||
return resultingKubeConfig
|
||||
}
|
||||
|
||||
// parsePEMCert decodes a PEM-formatted certificate and returns it as an x509.Certificate
|
||||
func parsePEMCert(certData []byte) (*x509.Certificate, error) {
|
||||
pemBlock, trailingData := pem.Decode(certData)
|
||||
if pemBlock == nil {
|
||||
return nil, fmt.Errorf("invalid PEM data")
|
||||
}
|
||||
if len(trailingData) != 0 {
|
||||
return nil, fmt.Errorf("trailing data after first PEM block")
|
||||
}
|
||||
return x509.ParseCertificate(pemBlock.Bytes)
|
||||
}
|
||||
115
vendor/k8s.io/kubernetes/cmd/kubeadm/app/discovery/token/token_test.go
generated
vendored
Normal file
115
vendor/k8s.io/kubernetes/cmd/kubeadm/app/discovery/token/token_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
Copyright 2017 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 token
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||||
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
|
||||
)
|
||||
|
||||
// testCertPEM is a simple self-signed test certificate issued with the openssl CLI:
|
||||
// openssl req -new -newkey rsa:2048 -days 36500 -nodes -x509 -keyout /dev/null -out test.crt
|
||||
const testCertPEM = `
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDRDCCAiygAwIBAgIJAJgVaCXvC6HkMA0GCSqGSIb3DQEBBQUAMB8xHTAbBgNV
|
||||
BAMTFGt1YmVhZG0ta2V5cGlucy10ZXN0MCAXDTE3MDcwNTE3NDMxMFoYDzIxMTcw
|
||||
NjExMTc0MzEwWjAfMR0wGwYDVQQDExRrdWJlYWRtLWtleXBpbnMtdGVzdDCCASIw
|
||||
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK0ba8mHU9UtYlzM1Own2Fk/XGjR
|
||||
J4uJQvSeGLtz1hID1IA0dLwruvgLCPadXEOw/f/IWIWcmT+ZmvIHZKa/woq2iHi5
|
||||
+HLhXs7aG4tjKGLYhag1hLjBI7icqV7ovkjdGAt9pWkxEzhIYClFMXDjKpMSynu+
|
||||
YX6nZ9tic1cOkHmx2yiZdMkuriRQnpTOa7bb03OC1VfGl7gHlOAIYaj4539WCOr8
|
||||
+ACTUMJUFEHcRZ2o8a/v6F9GMK+7SC8SJUI+GuroXqlMAdhEv4lX5Co52enYaClN
|
||||
+D9FJLRpBv2YfiCQdJRaiTvCBSxEFz6BN+PtP5l2Hs703ZWEkOqCByM6HV8CAwEA
|
||||
AaOBgDB+MB0GA1UdDgQWBBRQgUX8MhK2rWBWQiPHWcKzoWDH5DBPBgNVHSMESDBG
|
||||
gBRQgUX8MhK2rWBWQiPHWcKzoWDH5KEjpCEwHzEdMBsGA1UEAxMUa3ViZWFkbS1r
|
||||
ZXlwaW5zLXRlc3SCCQCYFWgl7wuh5DAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEB
|
||||
BQUAA4IBAQCaAUif7Pfx3X0F08cxhx8/Hdx4jcJw6MCq6iq6rsXM32ge43t8OHKC
|
||||
pJW08dk58a3O1YQSMMvD6GJDAiAfXzfwcwY6j258b1ZlI9Ag0VokvhMl/XfdCsdh
|
||||
AWImnL1t4hvU5jLaImUUMlYxMcSfHBGAm7WJIZ2LdEfg6YWfZh+WGbg1W7uxLxk6
|
||||
y4h5rWdNnzBHWAGf7zJ0oEDV6W6RSwNXtC0JNnLaeIUm/6xdSddJlQPwUv8YH4jX
|
||||
c1vuFqTnJBPcb7W//R/GI2Paicm1cmns9NLnPR35exHxFTy+D1yxmGokpoPMdife
|
||||
aH+sfuxT8xeTPb3kjzF9eJTlnEquUDLM
|
||||
-----END CERTIFICATE-----`
|
||||
|
||||
func TestRunForEndpointsAndReturnFirst(t *testing.T) {
|
||||
tests := []struct {
|
||||
endpoints []string
|
||||
expectedEndpoint string
|
||||
}{
|
||||
{
|
||||
endpoints: []string{"1", "2", "3"},
|
||||
expectedEndpoint: "1",
|
||||
},
|
||||
{
|
||||
endpoints: []string{"6", "5"},
|
||||
expectedEndpoint: "5",
|
||||
},
|
||||
{
|
||||
endpoints: []string{"10", "4"},
|
||||
expectedEndpoint: "4",
|
||||
},
|
||||
}
|
||||
for _, rt := range tests {
|
||||
returnKubeConfig := runForEndpointsAndReturnFirst(rt.endpoints, func(endpoint string) (*clientcmdapi.Config, error) {
|
||||
timeout, _ := strconv.Atoi(endpoint)
|
||||
time.Sleep(time.Second * time.Duration(timeout))
|
||||
return kubeconfigutil.CreateBasic(endpoint, "foo", "foo", []byte{}), nil
|
||||
})
|
||||
endpoint := returnKubeConfig.Clusters[returnKubeConfig.Contexts[returnKubeConfig.CurrentContext].Cluster].Server
|
||||
if endpoint != rt.expectedEndpoint {
|
||||
t.Errorf(
|
||||
"failed TestRunForEndpointsAndReturnFirst:\n\texpected: %s\n\t actual: %s",
|
||||
endpoint,
|
||||
rt.expectedEndpoint,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParsePEMCert(t *testing.T) {
|
||||
for _, testCase := range []struct {
|
||||
name string
|
||||
input []byte
|
||||
expectValid bool
|
||||
}{
|
||||
{"invalid certificate data", []byte{0}, false},
|
||||
{"certificate with junk appended", []byte(testCertPEM + "\nABC"), false},
|
||||
{"multiple certificates", []byte(testCertPEM + "\n" + testCertPEM), false},
|
||||
{"valid", []byte(testCertPEM), true},
|
||||
} {
|
||||
cert, err := parsePEMCert(testCase.input)
|
||||
if testCase.expectValid {
|
||||
if err != nil {
|
||||
t.Errorf("failed TestParsePEMCert(%s): unexpected error %v", testCase.name, err)
|
||||
}
|
||||
if cert == nil {
|
||||
t.Errorf("failed TestParsePEMCert(%s): returned nil", testCase.name)
|
||||
}
|
||||
} else {
|
||||
if err == nil {
|
||||
t.Errorf("failed TestParsePEMCert(%s): expected an error", testCase.name)
|
||||
}
|
||||
if cert != nil {
|
||||
t.Errorf("failed TestParsePEMCert(%s): expected not to get a certificate back, but got one", testCase.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
33
vendor/k8s.io/kubernetes/cmd/kubeadm/app/features/BUILD
generated
vendored
Normal file
33
vendor/k8s.io/kubernetes/cmd/kubeadm/app/features/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["features.go"],
|
||||
deps = ["//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["features_test.go"],
|
||||
library = ":go_default_library",
|
||||
deps = ["//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library"],
|
||||
)
|
||||
113
vendor/k8s.io/kubernetes/cmd/kubeadm/app/features/features.go
generated
vendored
Normal file
113
vendor/k8s.io/kubernetes/cmd/kubeadm/app/features/features.go
generated
vendored
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
Copyright 2017 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 features
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
)
|
||||
|
||||
const (
|
||||
// SelfHosting is beta in v1.8
|
||||
SelfHosting utilfeature.Feature = "SelfHosting"
|
||||
|
||||
// StoreCertsInSecrets is alpha in v1.8
|
||||
StoreCertsInSecrets utilfeature.Feature = "StoreCertsInSecrets"
|
||||
)
|
||||
|
||||
// FeatureList represents a list of feature gates
|
||||
type FeatureList map[utilfeature.Feature]utilfeature.FeatureSpec
|
||||
|
||||
// Enabled indicates whether a feature name has been enabled
|
||||
func Enabled(featureList map[string]bool, featureName utilfeature.Feature) bool {
|
||||
return featureList[string(featureName)]
|
||||
}
|
||||
|
||||
// Supports indicates whether a feature name is supported on the given
|
||||
// feature set
|
||||
func Supports(featureList FeatureList, featureName string) bool {
|
||||
for k := range featureList {
|
||||
if featureName == string(k) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Keys returns a slice of feature names for a given feature set
|
||||
func Keys(featureList FeatureList) []string {
|
||||
var list []string
|
||||
for k := range featureList {
|
||||
list = append(list, string(k))
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
// InitFeatureGates are the default feature gates for the init command
|
||||
var InitFeatureGates = FeatureList{
|
||||
SelfHosting: {Default: false, PreRelease: utilfeature.Alpha},
|
||||
StoreCertsInSecrets: {Default: false, PreRelease: utilfeature.Alpha},
|
||||
}
|
||||
|
||||
// KnownFeatures returns a slice of strings describing the FeatureList features.
|
||||
func KnownFeatures(f *FeatureList) []string {
|
||||
var known []string
|
||||
for k, v := range *f {
|
||||
pre := ""
|
||||
if v.PreRelease != utilfeature.GA {
|
||||
pre = fmt.Sprintf("%s - ", v.PreRelease)
|
||||
}
|
||||
known = append(known, fmt.Sprintf("%s=true|false (%sdefault=%t)", k, pre, v.Default))
|
||||
}
|
||||
sort.Strings(known)
|
||||
return known
|
||||
}
|
||||
|
||||
// NewFeatureGate parse a string of the form "key1=value1,key2=value2,..." into a
|
||||
// map[string]bool of known keys or returns an error.
|
||||
func NewFeatureGate(f *FeatureList, value string) (map[string]bool, error) {
|
||||
featureGate := map[string]bool{}
|
||||
for _, s := range strings.Split(value, ",") {
|
||||
if len(s) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
arr := strings.SplitN(s, "=", 2)
|
||||
if len(arr) != 2 {
|
||||
return nil, fmt.Errorf("missing bool value for feature-gate key:%s", s)
|
||||
}
|
||||
|
||||
k := strings.TrimSpace(arr[0])
|
||||
v := strings.TrimSpace(arr[1])
|
||||
|
||||
if !Supports(*f, k) {
|
||||
return nil, fmt.Errorf("unrecognized feature-gate key: %s", k)
|
||||
}
|
||||
|
||||
boolValue, err := strconv.ParseBool(v)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid value %v for feature-gate key: %s, use true|false instead", v, k)
|
||||
}
|
||||
featureGate[k] = boolValue
|
||||
}
|
||||
|
||||
return featureGate, nil
|
||||
}
|
||||
119
vendor/k8s.io/kubernetes/cmd/kubeadm/app/features/features_test.go
generated
vendored
Normal file
119
vendor/k8s.io/kubernetes/cmd/kubeadm/app/features/features_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
Copyright 2017 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 features
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
)
|
||||
|
||||
func TestKnownFeatures(t *testing.T) {
|
||||
var someFeatures = FeatureList{
|
||||
"feature2": {Default: true, PreRelease: utilfeature.Alpha},
|
||||
"feature1": {Default: false, PreRelease: utilfeature.Beta},
|
||||
"feature3": {Default: false, PreRelease: utilfeature.GA},
|
||||
}
|
||||
|
||||
r := KnownFeatures(&someFeatures)
|
||||
|
||||
if len(r) != 3 {
|
||||
t.Errorf("KnownFeatures returned %d values, expected 3", len(r))
|
||||
}
|
||||
|
||||
// check the first value is feature1 (the list should be sorted); prerelease and default should be present
|
||||
f1 := "feature1=true|false (BETA - default=false)"
|
||||
if r[0] != f1 {
|
||||
t.Errorf("KnownFeatures returned %s values, expected %s", r[0], f1)
|
||||
}
|
||||
// check the second value is feature2; prerelease and default should be present
|
||||
f2 := "feature2=true|false (ALPHA - default=true)"
|
||||
if r[1] != f2 {
|
||||
t.Errorf("KnownFeatures returned %s values, expected %s", r[1], f2)
|
||||
}
|
||||
// check the second value is feature3; prerelease should not shown fo GA features; default should be present
|
||||
f3 := "feature3=true|false (default=false)"
|
||||
if r[2] != f3 {
|
||||
t.Errorf("KnownFeatures returned %s values, expected %s", r[2], f3)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewFeatureGate(t *testing.T) {
|
||||
var someFeatures = FeatureList{
|
||||
"feature1": {Default: false, PreRelease: utilfeature.Beta},
|
||||
"feature2": {Default: true, PreRelease: utilfeature.Alpha},
|
||||
}
|
||||
|
||||
var tests = []struct {
|
||||
value string
|
||||
expectedError bool
|
||||
expectedFeaturesGate map[string]bool
|
||||
}{
|
||||
{ //invalid value (missing =)
|
||||
value: "invalidValue",
|
||||
expectedError: true,
|
||||
},
|
||||
{ //invalid value (missing =)
|
||||
value: "feature1=true,invalidValue",
|
||||
expectedError: true,
|
||||
},
|
||||
{ //invalid value (not a boolean)
|
||||
value: "feature1=notABoolean",
|
||||
expectedError: true,
|
||||
},
|
||||
{ //invalid value (not a boolean)
|
||||
value: "feature1=true,feature2=notABoolean",
|
||||
expectedError: true,
|
||||
},
|
||||
{ //unrecognized feature-gate key
|
||||
value: "unknownFeature=false",
|
||||
expectedError: true,
|
||||
},
|
||||
{ //unrecognized feature-gate key
|
||||
value: "feature1=true,unknownFeature=false",
|
||||
expectedError: true,
|
||||
},
|
||||
{ //one feature
|
||||
value: "feature1=true",
|
||||
expectedError: false,
|
||||
expectedFeaturesGate: map[string]bool{"feature1": true},
|
||||
},
|
||||
{ //two features
|
||||
value: "feature1=true,feature2=false",
|
||||
expectedError: false,
|
||||
expectedFeaturesGate: map[string]bool{"feature1": true, "feature2": false},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
||||
r, err := NewFeatureGate(&someFeatures, test.value)
|
||||
|
||||
if !test.expectedError && err != nil {
|
||||
t.Errorf("NewFeatureGate failed when not expected: %v", err)
|
||||
continue
|
||||
} else if test.expectedError && err == nil {
|
||||
t.Error("NewFeatureGate didn't failed when expected")
|
||||
continue
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(r, test.expectedFeaturesGate) {
|
||||
t.Errorf("NewFeatureGate returned a unexpected value")
|
||||
}
|
||||
}
|
||||
}
|
||||
36
vendor/k8s.io/kubernetes/cmd/kubeadm/app/images/BUILD
generated
vendored
Normal file
36
vendor/k8s.io/kubernetes/cmd/kubeadm/app/images/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["images.go"],
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/constants:go_default_library",
|
||||
"//cmd/kubeadm/app/util:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["images_test.go"],
|
||||
library = ":go_default_library",
|
||||
deps = ["//cmd/kubeadm/app/constants:go_default_library"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
38
vendor/k8s.io/kubernetes/cmd/kubeadm/app/images/images.go
generated
vendored
Normal file
38
vendor/k8s.io/kubernetes/cmd/kubeadm/app/images/images.go
generated
vendored
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
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 images
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||
)
|
||||
|
||||
func GetCoreImage(image, repoPrefix, k8sVersion, overrideImage string) string {
|
||||
if overrideImage != "" {
|
||||
return overrideImage
|
||||
}
|
||||
kubernetesImageTag := kubeadmutil.KubernetesVersionToImageTag(k8sVersion)
|
||||
return map[string]string{
|
||||
constants.Etcd: fmt.Sprintf("%s/%s-%s:%s", repoPrefix, "etcd", runtime.GOARCH, constants.DefaultEtcdVersion),
|
||||
constants.KubeAPIServer: fmt.Sprintf("%s/%s-%s:%s", repoPrefix, "kube-apiserver", runtime.GOARCH, kubernetesImageTag),
|
||||
constants.KubeControllerManager: fmt.Sprintf("%s/%s-%s:%s", repoPrefix, "kube-controller-manager", runtime.GOARCH, kubernetesImageTag),
|
||||
constants.KubeScheduler: fmt.Sprintf("%s/%s-%s:%s", repoPrefix, "kube-scheduler", runtime.GOARCH, kubernetesImageTag),
|
||||
}[image]
|
||||
}
|
||||
75
vendor/k8s.io/kubernetes/cmd/kubeadm/app/images/images_test.go
generated
vendored
Normal file
75
vendor/k8s.io/kubernetes/cmd/kubeadm/app/images/images_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
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 images
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
)
|
||||
|
||||
const (
|
||||
testversion = "v10.1.2-alpha.1.100+0123456789abcdef+SOMETHING"
|
||||
expected = "v10.1.2-alpha.1.100_0123456789abcdef_SOMETHING"
|
||||
gcrPrefix = "gcr.io/google_containers"
|
||||
)
|
||||
|
||||
func TestGetCoreImage(t *testing.T) {
|
||||
var tests = []struct {
|
||||
image, repo, version, override, expected string
|
||||
}{
|
||||
{
|
||||
override: "override",
|
||||
expected: "override",
|
||||
},
|
||||
{
|
||||
image: constants.Etcd,
|
||||
repo: gcrPrefix,
|
||||
expected: fmt.Sprintf("%s/%s-%s:%s", gcrPrefix, "etcd", runtime.GOARCH, constants.DefaultEtcdVersion),
|
||||
},
|
||||
{
|
||||
image: constants.KubeAPIServer,
|
||||
repo: gcrPrefix,
|
||||
version: testversion,
|
||||
expected: fmt.Sprintf("%s/%s-%s:%s", gcrPrefix, "kube-apiserver", runtime.GOARCH, expected),
|
||||
},
|
||||
{
|
||||
image: constants.KubeControllerManager,
|
||||
repo: gcrPrefix,
|
||||
version: testversion,
|
||||
expected: fmt.Sprintf("%s/%s-%s:%s", gcrPrefix, "kube-controller-manager", runtime.GOARCH, expected),
|
||||
},
|
||||
{
|
||||
image: constants.KubeScheduler,
|
||||
repo: gcrPrefix,
|
||||
version: testversion,
|
||||
expected: fmt.Sprintf("%s/%s-%s:%s", gcrPrefix, "kube-scheduler", runtime.GOARCH, expected),
|
||||
},
|
||||
}
|
||||
for _, rt := range tests {
|
||||
actual := GetCoreImage(rt.image, rt.repo, rt.version, rt.override)
|
||||
if actual != rt.expected {
|
||||
t.Errorf(
|
||||
"failed GetCoreImage:\n\texpected: %s\n\t actual: %s",
|
||||
rt.expected,
|
||||
actual,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
35
vendor/k8s.io/kubernetes/cmd/kubeadm/app/kubeadm.go
generated
vendored
Normal file
35
vendor/k8s.io/kubernetes/cmd/kubeadm/app/kubeadm.go
generated
vendored
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
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 app
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
_ "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/install"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/cmd"
|
||||
)
|
||||
|
||||
func Run() error {
|
||||
// We do not want these flags to show up in --help
|
||||
pflag.CommandLine.MarkHidden("google-json-key")
|
||||
pflag.CommandLine.MarkHidden("log-flush-frequency")
|
||||
|
||||
cmd := cmd.NewKubeadmCommand(os.Stdin, os.Stdout, os.Stderr)
|
||||
return cmd.Execute()
|
||||
}
|
||||
50
vendor/k8s.io/kubernetes/cmd/kubeadm/app/node/BUILD
generated
vendored
Normal file
50
vendor/k8s.io/kubernetes/cmd/kubeadm/app/node/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"csr.go",
|
||||
"validate.go",
|
||||
],
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/util/kubeconfig:go_default_library",
|
||||
"//pkg/kubelet/util/csr:go_default_library",
|
||||
"//vendor/k8s.io/api/certificates/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/clientcmd/api:go_default_library",
|
||||
"//vendor/k8s.io/client-go/util/cert:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["validate_test.go"],
|
||||
library = ":go_default_library",
|
||||
deps = [
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/version:go_default_library",
|
||||
"//vendor/k8s.io/client-go/discovery:go_default_library",
|
||||
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
||||
"//vendor/k8s.io/client-go/rest:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
62
vendor/k8s.io/kubernetes/cmd/kubeadm/app/node/csr.go
generated
vendored
Normal file
62
vendor/k8s.io/kubernetes/cmd/kubeadm/app/node/csr.go
generated
vendored
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
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 node
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||||
certutil "k8s.io/client-go/util/cert"
|
||||
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
|
||||
"k8s.io/kubernetes/pkg/kubelet/util/csr"
|
||||
)
|
||||
|
||||
// CSRContextAndUser defines the context to use for the client certs in the kubelet kubeconfig file
|
||||
const CSRContextAndUser = "kubelet-csr"
|
||||
|
||||
// PerformTLSBootstrap executes a node certificate signing request.
|
||||
func PerformTLSBootstrap(cfg *clientcmdapi.Config, hostName string) error {
|
||||
client, err := kubeconfigutil.KubeConfigToClientSet(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println("[csr] Created API client to obtain unique certificate for this node, generating keys and certificate signing request")
|
||||
|
||||
key, err := certutil.MakeEllipticPrivateKeyPEM()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to generate private key [%v]", err)
|
||||
}
|
||||
|
||||
cert, err := csr.RequestNodeCertificate(client.CertificatesV1beta1().CertificateSigningRequests(), key, types.NodeName(hostName))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to request signed certificate from the API server [%v]", err)
|
||||
}
|
||||
fmt.Println("[csr] Received signed certificate from the API server, generating KubeConfig...")
|
||||
|
||||
cfg.AuthInfos[CSRContextAndUser] = &clientcmdapi.AuthInfo{
|
||||
ClientKeyData: key,
|
||||
ClientCertificateData: cert,
|
||||
}
|
||||
cfg.Contexts[CSRContextAndUser] = &clientcmdapi.Context{
|
||||
AuthInfo: CSRContextAndUser,
|
||||
Cluster: cfg.Contexts[cfg.CurrentContext].Cluster,
|
||||
}
|
||||
cfg.CurrentContext = CSRContextAndUser
|
||||
return nil
|
||||
}
|
||||
51
vendor/k8s.io/kubernetes/cmd/kubeadm/app/node/validate.go
generated
vendored
Normal file
51
vendor/k8s.io/kubernetes/cmd/kubeadm/app/node/validate.go
generated
vendored
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
Copyright 2017 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 node
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
certsapi "k8s.io/api/certificates/v1beta1"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
)
|
||||
|
||||
// ValidateAPIServer makes sure the server we're connecting to supports the Beta Certificates API
|
||||
func ValidateAPIServer(client clientset.Interface) error {
|
||||
version, err := client.Discovery().ServerVersion()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to check server version: %v", err)
|
||||
}
|
||||
fmt.Printf("[bootstrap] Detected server version: %s\n", version.String())
|
||||
|
||||
// Check certificates API. If the server supports the version of the Certificates API we're using, we're good to go
|
||||
serverGroups, err := client.Discovery().ServerGroups()
|
||||
if err != nil {
|
||||
return fmt.Errorf("certificate API check failed: failed to retrieve a list of supported API objects [%v]", err)
|
||||
}
|
||||
for _, group := range serverGroups.Groups {
|
||||
if group.Name == certsapi.SchemeGroupVersion.Group {
|
||||
for _, version := range group.Versions {
|
||||
if version.Version == certsapi.SchemeGroupVersion.Version {
|
||||
fmt.Printf("[bootstrap] The server supports the Certificates API (%s/%s)\n", certsapi.SchemeGroupVersion.Group, certsapi.SchemeGroupVersion.Version)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("certificate API check failed: API server with version %s doesn't support Certificates API (%s/%s), use v1.6.0 or newer",
|
||||
version.String(), certsapi.SchemeGroupVersion.Group, certsapi.SchemeGroupVersion.Version)
|
||||
}
|
||||
145
vendor/k8s.io/kubernetes/cmd/kubeadm/app/node/validate_test.go
generated
vendored
Normal file
145
vendor/k8s.io/kubernetes/cmd/kubeadm/app/node/validate_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
/*
|
||||
Copyright 2017 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 node
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/version"
|
||||
"k8s.io/client-go/discovery"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
func TestValidateAPIServer(t *testing.T) {
|
||||
expect := version.Info{
|
||||
Major: "foo",
|
||||
Minor: "bar",
|
||||
GitCommit: "baz",
|
||||
}
|
||||
tests := []struct {
|
||||
s *httptest.Server
|
||||
expect bool
|
||||
}{
|
||||
{
|
||||
s: httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {})),
|
||||
expect: false,
|
||||
},
|
||||
{
|
||||
s: httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
var obj interface{}
|
||||
switch req.URL.Path {
|
||||
case "/api":
|
||||
obj = &metav1.APIVersions{
|
||||
Versions: []string{
|
||||
"v1.6.0",
|
||||
},
|
||||
}
|
||||
output, err := json.Marshal(obj)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected encoding error: %v", err)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(output)
|
||||
default:
|
||||
output, err := json.Marshal(expect)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected encoding error: %v", err)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(output)
|
||||
}
|
||||
})),
|
||||
expect: false,
|
||||
},
|
||||
{
|
||||
s: httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
var obj interface{}
|
||||
switch req.URL.Path {
|
||||
case "/api":
|
||||
obj = &metav1.APIVersions{
|
||||
Versions: []string{
|
||||
"v1.6.0",
|
||||
},
|
||||
}
|
||||
output, err := json.Marshal(obj)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected encoding error: %v", err)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(output)
|
||||
case "/apis":
|
||||
obj = &metav1.APIGroupList{
|
||||
Groups: []metav1.APIGroup{
|
||||
{
|
||||
Name: "certificates.k8s.io",
|
||||
Versions: []metav1.GroupVersionForDiscovery{
|
||||
{GroupVersion: "certificates.k8s.io/v1beta1", Version: "v1beta1"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
output, err := json.Marshal(obj)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected encoding error: %v", err)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(output)
|
||||
default:
|
||||
output, err := json.Marshal(expect)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected encoding error: %v", err)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(output)
|
||||
}
|
||||
})),
|
||||
expect: true,
|
||||
},
|
||||
}
|
||||
for _, rt := range tests {
|
||||
defer rt.s.Close()
|
||||
rc := &restclient.Config{Host: rt.s.URL}
|
||||
c, err := discovery.NewDiscoveryClientForConfig(rc)
|
||||
if err != nil {
|
||||
t.Fatalf("encountered an error while trying to get the new discovery client: %v", err)
|
||||
}
|
||||
cs := &clientset.Clientset{DiscoveryClient: c}
|
||||
actual := ValidateAPIServer(cs)
|
||||
if (actual == nil) != rt.expect {
|
||||
t.Errorf(
|
||||
"failed TestValidateAPIServer:\n\texpected: %t\n\t actual: %t",
|
||||
rt.expect,
|
||||
(actual == nil),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
65
vendor/k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/dns/BUILD
generated
vendored
Normal file
65
vendor/k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/dns/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"dns_test.go",
|
||||
"versions_test.go",
|
||||
],
|
||||
library = ":go_default_library",
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/util:go_default_library",
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/util/version:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/client-go/kubernetes/fake:go_default_library",
|
||||
"//vendor/k8s.io/client-go/testing:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"dns.go",
|
||||
"manifests.go",
|
||||
"versions.go",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||
"//cmd/kubeadm/app/constants:go_default_library",
|
||||
"//cmd/kubeadm/app/util:go_default_library",
|
||||
"//cmd/kubeadm/app/util/apiclient:go_default_library",
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/util/version:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/api/extensions/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
147
vendor/k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/dns/dns.go
generated
vendored
Normal file
147
vendor/k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/dns/dns.go
generated
vendored
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
Copyright 2017 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 dns
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"runtime"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
extensions "k8s.io/api/extensions/v1beta1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
kuberuntime "k8s.io/apimachinery/pkg/runtime"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/util/version"
|
||||
)
|
||||
|
||||
const (
|
||||
// KubeDNSServiceAccountName describes the name of the ServiceAccount for the kube-dns addon
|
||||
KubeDNSServiceAccountName = "kube-dns"
|
||||
)
|
||||
|
||||
// EnsureDNSAddon creates the kube-dns addon
|
||||
func EnsureDNSAddon(cfg *kubeadmapi.MasterConfiguration, client clientset.Interface) error {
|
||||
k8sVersion, err := version.ParseSemantic(cfg.KubernetesVersion)
|
||||
if err != nil {
|
||||
return fmt.Errorf("couldn't parse kubernetes version %q: %v", cfg.KubernetesVersion, err)
|
||||
}
|
||||
|
||||
if err := CreateServiceAccount(client); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Get the YAML manifest conditionally based on the k8s version
|
||||
kubeDNSDeploymentBytes := GetKubeDNSManifest(k8sVersion)
|
||||
dnsDeploymentBytes, err := kubeadmutil.ParseTemplate(kubeDNSDeploymentBytes, struct{ ImageRepository, Arch, Version, DNSDomain, MasterTaintKey string }{
|
||||
ImageRepository: cfg.ImageRepository,
|
||||
Arch: runtime.GOARCH,
|
||||
// Get the kube-dns version conditionally based on the k8s version
|
||||
Version: GetKubeDNSVersion(k8sVersion),
|
||||
DNSDomain: cfg.Networking.DNSDomain,
|
||||
MasterTaintKey: kubeadmconstants.LabelNodeRoleMaster,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("error when parsing kube-dns deployment template: %v", err)
|
||||
}
|
||||
|
||||
dnsip, err := getDNSIP(client)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dnsServiceBytes, err := kubeadmutil.ParseTemplate(KubeDNSService, struct{ DNSIP string }{
|
||||
DNSIP: dnsip.String(),
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("error when parsing kube-proxy configmap template: %v", err)
|
||||
}
|
||||
|
||||
if err := createKubeDNSAddon(dnsDeploymentBytes, dnsServiceBytes, client); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("[addons] Applied essential addon: kube-dns")
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateServiceAccount creates the necessary serviceaccounts that kubeadm uses/might use, if they don't already exist.
|
||||
func CreateServiceAccount(client clientset.Interface) error {
|
||||
|
||||
return apiclient.CreateOrUpdateServiceAccount(client, &v1.ServiceAccount{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: KubeDNSServiceAccountName,
|
||||
Namespace: metav1.NamespaceSystem,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func createKubeDNSAddon(deploymentBytes, serviceBytes []byte, client clientset.Interface) error {
|
||||
kubednsDeployment := &extensions.Deployment{}
|
||||
if err := kuberuntime.DecodeInto(api.Codecs.UniversalDecoder(), deploymentBytes, kubednsDeployment); err != nil {
|
||||
return fmt.Errorf("unable to decode kube-dns deployment %v", err)
|
||||
}
|
||||
|
||||
// Create the Deployment for kube-dns or update it in case it already exists
|
||||
if err := apiclient.CreateOrUpdateDeployment(client, kubednsDeployment); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
kubednsService := &v1.Service{}
|
||||
if err := kuberuntime.DecodeInto(api.Codecs.UniversalDecoder(), serviceBytes, kubednsService); err != nil {
|
||||
return fmt.Errorf("unable to decode kube-dns service %v", err)
|
||||
}
|
||||
|
||||
// Can't use a generic apiclient helper func here as we have to tolerate more than AlreadyExists.
|
||||
if _, err := client.CoreV1().Services(metav1.NamespaceSystem).Create(kubednsService); err != nil {
|
||||
// Ignore if the Service is invalid with this error message:
|
||||
// Service "kube-dns" is invalid: spec.clusterIP: Invalid value: "10.96.0.10": provided IP is already allocated
|
||||
|
||||
if !apierrors.IsAlreadyExists(err) && !apierrors.IsInvalid(err) {
|
||||
return fmt.Errorf("unable to create a new kube-dns service: %v", err)
|
||||
}
|
||||
|
||||
if _, err := client.CoreV1().Services(metav1.NamespaceSystem).Update(kubednsService); err != nil {
|
||||
return fmt.Errorf("unable to create/update the kube-dns service: %v", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// getDNSIP fetches the kubernetes service's ClusterIP and appends a "0" to it in order to get the DNS IP
|
||||
func getDNSIP(client clientset.Interface) (net.IP, error) {
|
||||
k8ssvc, err := client.CoreV1().Services(metav1.NamespaceDefault).Get("kubernetes", metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("couldn't fetch information about the kubernetes service: %v", err)
|
||||
}
|
||||
|
||||
if len(k8ssvc.Spec.ClusterIP) == 0 {
|
||||
return nil, fmt.Errorf("couldn't fetch a valid clusterIP from the kubernetes service")
|
||||
}
|
||||
|
||||
// Build an IP by taking the kubernetes service's clusterIP and appending a "0" and checking that it's valid
|
||||
dnsIP := net.ParseIP(fmt.Sprintf("%s0", k8ssvc.Spec.ClusterIP))
|
||||
if dnsIP == nil {
|
||||
return nil, fmt.Errorf("could not parse dns ip %q: %v", dnsIP, err)
|
||||
}
|
||||
return dnsIP, nil
|
||||
}
|
||||
121
vendor/k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/dns/dns_test.go
generated
vendored
Normal file
121
vendor/k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/dns/dns_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
Copyright 2017 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 dns
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
clientsetfake "k8s.io/client-go/kubernetes/fake"
|
||||
core "k8s.io/client-go/testing"
|
||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
)
|
||||
|
||||
func TestCreateServiceAccount(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
createErr error
|
||||
expectErr bool
|
||||
}{
|
||||
{
|
||||
"error-free case",
|
||||
nil,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"duplication errors should be ignored",
|
||||
apierrors.NewAlreadyExists(api.Resource(""), ""),
|
||||
false,
|
||||
},
|
||||
{
|
||||
"unexpected errors should be returned",
|
||||
apierrors.NewUnauthorized(""),
|
||||
true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
client := clientsetfake.NewSimpleClientset()
|
||||
if tc.createErr != nil {
|
||||
client.PrependReactor("create", "serviceaccounts", func(action core.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, tc.createErr
|
||||
})
|
||||
}
|
||||
|
||||
err := CreateServiceAccount(client)
|
||||
if tc.expectErr {
|
||||
if err == nil {
|
||||
t.Errorf("CreateServiceAccounts(%s) wanted err, got nil", tc.name)
|
||||
}
|
||||
continue
|
||||
} else if !tc.expectErr && err != nil {
|
||||
t.Errorf("CreateServiceAccounts(%s) returned unexpected err: %v", tc.name, err)
|
||||
}
|
||||
|
||||
wantResourcesCreated := 1
|
||||
if len(client.Actions()) != wantResourcesCreated {
|
||||
t.Errorf("CreateServiceAccounts(%s) should have made %d actions, but made %d", tc.name, wantResourcesCreated, len(client.Actions()))
|
||||
}
|
||||
|
||||
for _, action := range client.Actions() {
|
||||
if action.GetVerb() != "create" || action.GetResource().Resource != "serviceaccounts" {
|
||||
t.Errorf("CreateServiceAccounts(%s) called [%v %v], but wanted [create serviceaccounts]",
|
||||
tc.name, action.GetVerb(), action.GetResource().Resource)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func TestCompileManifests(t *testing.T) {
|
||||
var tests = []struct {
|
||||
manifest string
|
||||
data interface{}
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
manifest: v170AndAboveKubeDNSDeployment,
|
||||
data: struct{ ImageRepository, Arch, Version, DNSDomain, MasterTaintKey string }{
|
||||
ImageRepository: "foo",
|
||||
Arch: "foo",
|
||||
Version: "foo",
|
||||
DNSDomain: "foo",
|
||||
MasterTaintKey: "foo",
|
||||
},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
manifest: KubeDNSService,
|
||||
data: struct{ DNSIP string }{
|
||||
DNSIP: "foo",
|
||||
},
|
||||
expected: true,
|
||||
},
|
||||
}
|
||||
for _, rt := range tests {
|
||||
_, actual := kubeadmutil.ParseTemplate(rt.manifest, rt.data)
|
||||
if (actual == nil) != rt.expected {
|
||||
t.Errorf(
|
||||
"failed CompileManifests:\n\texpected: %t\n\t actual: %t",
|
||||
rt.expected,
|
||||
(actual == nil),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
215
vendor/k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/dns/manifests.go
generated
vendored
Normal file
215
vendor/k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/dns/manifests.go
generated
vendored
Normal file
|
|
@ -0,0 +1,215 @@
|
|||
/*
|
||||
Copyright 2017 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 dns
|
||||
|
||||
const (
|
||||
// v170AndAboveKubeDNSDeployment is the kube-dns Deployment manifest for the kube-dns manifest for v1.7+
|
||||
v170AndAboveKubeDNSDeployment = `
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: kube-dns
|
||||
namespace: kube-system
|
||||
labels:
|
||||
k8s-app: kube-dns
|
||||
spec:
|
||||
# replicas: not specified here:
|
||||
# 1. In order to make Addon Manager do not reconcile this replicas parameter.
|
||||
# 2. Default is 1.
|
||||
# 3. Will be tuned in real time if DNS horizontal auto-scaling is turned on.
|
||||
strategy:
|
||||
rollingUpdate:
|
||||
maxSurge: 10%
|
||||
maxUnavailable: 0
|
||||
selector:
|
||||
matchLabels:
|
||||
k8s-app: kube-dns
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
k8s-app: kube-dns
|
||||
spec:
|
||||
volumes:
|
||||
- name: kube-dns-config
|
||||
configMap:
|
||||
name: kube-dns
|
||||
optional: true
|
||||
containers:
|
||||
- name: kubedns
|
||||
image: {{ .ImageRepository }}/k8s-dns-kube-dns-{{ .Arch }}:{{ .Version }}
|
||||
imagePullPolicy: IfNotPresent
|
||||
resources:
|
||||
# TODO: Set memory limits when we've profiled the container for large
|
||||
# clusters, then set request = limit to keep this container in
|
||||
# guaranteed class. Currently, this container falls into the
|
||||
# "burstable" category so the kubelet doesn't backoff from restarting it.
|
||||
limits:
|
||||
memory: 170Mi
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 70Mi
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /healthcheck/kubedns
|
||||
port: 10054
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 60
|
||||
timeoutSeconds: 5
|
||||
successThreshold: 1
|
||||
failureThreshold: 5
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /readiness
|
||||
port: 8081
|
||||
scheme: HTTP
|
||||
# we poll on pod startup for the Kubernetes master service and
|
||||
# only setup the /readiness HTTP server once that's available.
|
||||
initialDelaySeconds: 3
|
||||
timeoutSeconds: 5
|
||||
args:
|
||||
- --domain={{ .DNSDomain }}.
|
||||
- --dns-port=10053
|
||||
- --config-dir=/kube-dns-config
|
||||
- --v=2
|
||||
env:
|
||||
- name: PROMETHEUS_PORT
|
||||
value: "10055"
|
||||
ports:
|
||||
- containerPort: 10053
|
||||
name: dns-local
|
||||
protocol: UDP
|
||||
- containerPort: 10053
|
||||
name: dns-tcp-local
|
||||
protocol: TCP
|
||||
- containerPort: 10055
|
||||
name: metrics
|
||||
protocol: TCP
|
||||
volumeMounts:
|
||||
- name: kube-dns-config
|
||||
mountPath: /kube-dns-config
|
||||
- name: dnsmasq
|
||||
image: {{ .ImageRepository }}/k8s-dns-dnsmasq-nanny-{{ .Arch }}:{{ .Version }}
|
||||
imagePullPolicy: IfNotPresent
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /healthcheck/dnsmasq
|
||||
port: 10054
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 60
|
||||
timeoutSeconds: 5
|
||||
successThreshold: 1
|
||||
failureThreshold: 5
|
||||
args:
|
||||
- -v=2
|
||||
- -logtostderr
|
||||
- -configDir=/etc/k8s/dns/dnsmasq-nanny
|
||||
- -restartDnsmasq=true
|
||||
- --
|
||||
- -k
|
||||
- --cache-size=1000
|
||||
- --log-facility=-
|
||||
- --server=/{{ .DNSDomain }}/127.0.0.1#10053
|
||||
- --server=/in-addr.arpa/127.0.0.1#10053
|
||||
- --server=/ip6.arpa/127.0.0.1#10053
|
||||
ports:
|
||||
- containerPort: 53
|
||||
name: dns
|
||||
protocol: UDP
|
||||
- containerPort: 53
|
||||
name: dns-tcp
|
||||
protocol: TCP
|
||||
# see: https://github.com/kubernetes/kubernetes/issues/29055 for details
|
||||
resources:
|
||||
requests:
|
||||
cpu: 150m
|
||||
memory: 20Mi
|
||||
volumeMounts:
|
||||
- name: kube-dns-config
|
||||
mountPath: /etc/k8s/dns/dnsmasq-nanny
|
||||
- name: sidecar
|
||||
image: {{ .ImageRepository }}/k8s-dns-sidecar-{{ .Arch }}:{{ .Version }}
|
||||
imagePullPolicy: IfNotPresent
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /metrics
|
||||
port: 10054
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 60
|
||||
timeoutSeconds: 5
|
||||
successThreshold: 1
|
||||
failureThreshold: 5
|
||||
args:
|
||||
- --v=2
|
||||
- --logtostderr
|
||||
- --probe=kubedns,127.0.0.1:10053,kubernetes.default.svc.{{ .DNSDomain }},5,A
|
||||
- --probe=dnsmasq,127.0.0.1:53,kubernetes.default.svc.{{ .DNSDomain }},5,A
|
||||
ports:
|
||||
- containerPort: 10054
|
||||
name: metrics
|
||||
protocol: TCP
|
||||
resources:
|
||||
requests:
|
||||
memory: 20Mi
|
||||
cpu: 10m
|
||||
dnsPolicy: Default # Don't use cluster DNS.
|
||||
serviceAccountName: kube-dns
|
||||
tolerations:
|
||||
- key: CriticalAddonsOnly
|
||||
operator: Exists
|
||||
- key: {{ .MasterTaintKey }}
|
||||
effect: NoSchedule
|
||||
# TODO: Remove this affinity field as soon as we are using manifest lists
|
||||
affinity:
|
||||
nodeAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
nodeSelectorTerms:
|
||||
- matchExpressions:
|
||||
- key: beta.kubernetes.io/arch
|
||||
operator: In
|
||||
values:
|
||||
- {{ .Arch }}
|
||||
`
|
||||
|
||||
// KubeDNSService is the kube-dns Service manifest
|
||||
KubeDNSService = `
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
k8s-app: kube-dns
|
||||
kubernetes.io/cluster-service: "true"
|
||||
kubernetes.io/name: "KubeDNS"
|
||||
name: kube-dns
|
||||
namespace: kube-system
|
||||
# Without this resourceVersion value, an update of the Service between versions will yield:
|
||||
# Service "kube-dns" is invalid: metadata.resourceVersion: Invalid value: "": must be specified for an update
|
||||
resourceVersion: "0"
|
||||
spec:
|
||||
clusterIP: {{ .DNSIP }}
|
||||
ports:
|
||||
- name: dns
|
||||
port: 53
|
||||
protocol: UDP
|
||||
targetPort: 53
|
||||
- name: dns-tcp
|
||||
port: 53
|
||||
protocol: TCP
|
||||
targetPort: 53
|
||||
selector:
|
||||
k8s-app: kube-dns
|
||||
`
|
||||
)
|
||||
40
vendor/k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/dns/versions.go
generated
vendored
Normal file
40
vendor/k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/dns/versions.go
generated
vendored
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
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 dns
|
||||
|
||||
import (
|
||||
"k8s.io/kubernetes/pkg/util/version"
|
||||
)
|
||||
|
||||
const (
|
||||
kubeDNSv170AndAboveVersion = "1.14.5"
|
||||
)
|
||||
|
||||
// GetKubeDNSVersion returns the right kube-dns version for a specific k8s version
|
||||
func GetKubeDNSVersion(kubeVersion *version.Version) string {
|
||||
// v1.7.0+ uses 1.14.5, just return that here
|
||||
// In the future when the kube-dns version is bumped at HEAD; add conditional logic to return the right versions
|
||||
// Also, the version might be bumped for different k8s releases on the same branch
|
||||
return kubeDNSv170AndAboveVersion
|
||||
}
|
||||
|
||||
// GetKubeDNSManifest returns the right kube-dns YAML manifest for a specific k8s version
|
||||
func GetKubeDNSManifest(kubeVersion *version.Version) string {
|
||||
// v1.7.0+ has only one known YAML manifest spec, just return that here
|
||||
// In the future when the kube-dns version is bumped at HEAD; add conditional logic to return the right manifest
|
||||
return v170AndAboveKubeDNSDeployment
|
||||
}
|
||||
70
vendor/k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/dns/versions_test.go
generated
vendored
Normal file
70
vendor/k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/dns/versions_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
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 dns
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/util/version"
|
||||
)
|
||||
|
||||
func TestGetKubeDNSVersion(t *testing.T) {
|
||||
var tests = []struct {
|
||||
k8sVersion, expected string
|
||||
}{
|
||||
{
|
||||
k8sVersion: "v1.7.0",
|
||||
expected: "1.14.5",
|
||||
},
|
||||
{
|
||||
k8sVersion: "v1.7.1",
|
||||
expected: "1.14.5",
|
||||
},
|
||||
{
|
||||
k8sVersion: "v1.7.2",
|
||||
expected: "1.14.5",
|
||||
},
|
||||
{
|
||||
k8sVersion: "v1.7.3",
|
||||
expected: "1.14.5",
|
||||
},
|
||||
{
|
||||
k8sVersion: "v1.8.0-alpha.2",
|
||||
expected: "1.14.5",
|
||||
},
|
||||
{
|
||||
k8sVersion: "v1.8.0",
|
||||
expected: "1.14.5",
|
||||
},
|
||||
}
|
||||
for _, rt := range tests {
|
||||
|
||||
k8sVersion, err := version.ParseSemantic(rt.k8sVersion)
|
||||
if err != nil {
|
||||
t.Fatalf("couldn't parse kubernetes version %q: %v", rt.k8sVersion, err)
|
||||
}
|
||||
|
||||
actualDNSVersion := GetKubeDNSVersion(k8sVersion)
|
||||
if actualDNSVersion != rt.expected {
|
||||
t.Errorf(
|
||||
"failed GetKubeDNSVersion:\n\texpected: %s\n\t actual: %s",
|
||||
rt.expected,
|
||||
actualDNSVersion,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
57
vendor/k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/proxy/BUILD
generated
vendored
Normal file
57
vendor/k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/proxy/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["proxy_test.go"],
|
||||
library = ":go_default_library",
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/util:go_default_library",
|
||||
"//pkg/api:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/client-go/kubernetes/fake:go_default_library",
|
||||
"//vendor/k8s.io/client-go/testing:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"manifests.go",
|
||||
"proxy.go",
|
||||
],
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||
"//cmd/kubeadm/app/constants:go_default_library",
|
||||
"//cmd/kubeadm/app/util:go_default_library",
|
||||
"//cmd/kubeadm/app/util/apiclient:go_default_library",
|
||||
"//pkg/api:go_default_library",
|
||||
"//plugin/pkg/scheduler/algorithm:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/api/extensions/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/api/rbac/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
104
vendor/k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/proxy/manifests.go
generated
vendored
Normal file
104
vendor/k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/proxy/manifests.go
generated
vendored
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
Copyright 2017 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 proxy
|
||||
|
||||
const (
|
||||
// KubeProxyConfigMap is the proxy ConfigMap manifest
|
||||
KubeProxyConfigMap = `
|
||||
kind: ConfigMap
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: kube-proxy
|
||||
namespace: kube-system
|
||||
labels:
|
||||
app: kube-proxy
|
||||
data:
|
||||
kubeconfig.conf: |
|
||||
apiVersion: v1
|
||||
kind: Config
|
||||
clusters:
|
||||
- cluster:
|
||||
certificate-authority: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
|
||||
server: {{ .MasterEndpoint }}
|
||||
name: default
|
||||
contexts:
|
||||
- context:
|
||||
cluster: default
|
||||
namespace: default
|
||||
user: default
|
||||
name: default
|
||||
current-context: default
|
||||
users:
|
||||
- name: default
|
||||
user:
|
||||
tokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token
|
||||
`
|
||||
|
||||
// KubeProxyDaemonSet is the proxy DaemonSet manifest
|
||||
KubeProxyDaemonSet = `
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: DaemonSet
|
||||
metadata:
|
||||
labels:
|
||||
k8s-app: kube-proxy
|
||||
name: kube-proxy
|
||||
namespace: kube-system
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
k8s-app: kube-proxy
|
||||
updateStrategy:
|
||||
type: RollingUpdate
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
k8s-app: kube-proxy
|
||||
spec:
|
||||
containers:
|
||||
- name: kube-proxy
|
||||
image: {{ if .ImageOverride }}{{ .ImageOverride }}{{ else }}{{ .ImageRepository }}/kube-proxy-{{ .Arch }}:{{ .Version }}{{ end }}
|
||||
imagePullPolicy: IfNotPresent
|
||||
command:
|
||||
- /usr/local/bin/kube-proxy
|
||||
- --kubeconfig=/var/lib/kube-proxy/kubeconfig.conf
|
||||
{{ .ClusterCIDR }}
|
||||
securityContext:
|
||||
privileged: true
|
||||
volumeMounts:
|
||||
- mountPath: /var/lib/kube-proxy
|
||||
name: kube-proxy
|
||||
- mountPath: /run/xtables.lock
|
||||
name: xtables-lock
|
||||
readOnly: false
|
||||
hostNetwork: true
|
||||
serviceAccountName: kube-proxy
|
||||
tolerations:
|
||||
- key: {{ .MasterTaintKey }}
|
||||
effect: NoSchedule
|
||||
- key: {{ .CloudTaintKey }}
|
||||
value: "true"
|
||||
effect: NoSchedule
|
||||
volumes:
|
||||
- name: kube-proxy
|
||||
configMap:
|
||||
name: kube-proxy
|
||||
- name: xtables-lock
|
||||
hostPath:
|
||||
path: /run/xtables.lock
|
||||
type: FileOrCreate
|
||||
`
|
||||
)
|
||||
156
vendor/k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/proxy/proxy.go
generated
vendored
Normal file
156
vendor/k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/proxy/proxy.go
generated
vendored
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
Copyright 2017 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 proxy
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
extensions "k8s.io/api/extensions/v1beta1"
|
||||
rbac "k8s.io/api/rbac/v1beta1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
kuberuntime "k8s.io/apimachinery/pkg/runtime"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/plugin/pkg/scheduler/algorithm"
|
||||
)
|
||||
|
||||
const (
|
||||
// KubeProxyClusterRoleName sets the name for the kube-proxy ClusterRole
|
||||
// TODO: This k8s-generic, well-known constant should be fetchable from another source, not be in this package
|
||||
KubeProxyClusterRoleName = "system:node-proxier"
|
||||
|
||||
// KubeProxyServiceAccountName describes the name of the ServiceAccount for the kube-proxy addon
|
||||
KubeProxyServiceAccountName = "kube-proxy"
|
||||
)
|
||||
|
||||
// EnsureProxyAddon creates the kube-proxy addons
|
||||
func EnsureProxyAddon(cfg *kubeadmapi.MasterConfiguration, client clientset.Interface) error {
|
||||
if err := CreateServiceAccount(client); err != nil {
|
||||
return fmt.Errorf("error when creating kube-proxy service account: %v", err)
|
||||
}
|
||||
|
||||
// Generate Master Enpoint kubeconfig file
|
||||
masterEndpoint, err := kubeadmutil.GetMasterEndpoint(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
proxyConfigMapBytes, err := kubeadmutil.ParseTemplate(KubeProxyConfigMap, struct{ MasterEndpoint string }{
|
||||
// Fetch this value from the kubeconfig file
|
||||
MasterEndpoint: masterEndpoint})
|
||||
if err != nil {
|
||||
return fmt.Errorf("error when parsing kube-proxy configmap template: %v", err)
|
||||
}
|
||||
|
||||
proxyDaemonSetBytes, err := kubeadmutil.ParseTemplate(KubeProxyDaemonSet, struct{ ImageRepository, Arch, Version, ImageOverride, ClusterCIDR, MasterTaintKey, CloudTaintKey string }{
|
||||
ImageRepository: cfg.GetControlPlaneImageRepository(),
|
||||
Arch: runtime.GOARCH,
|
||||
Version: kubeadmutil.KubernetesVersionToImageTag(cfg.KubernetesVersion),
|
||||
ImageOverride: cfg.UnifiedControlPlaneImage,
|
||||
ClusterCIDR: getClusterCIDR(cfg.Networking.PodSubnet),
|
||||
MasterTaintKey: kubeadmconstants.LabelNodeRoleMaster,
|
||||
CloudTaintKey: algorithm.TaintExternalCloudProvider,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("error when parsing kube-proxy daemonset template: %v", err)
|
||||
}
|
||||
|
||||
if err := createKubeProxyAddon(proxyConfigMapBytes, proxyDaemonSetBytes, client); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := CreateRBACRules(client); err != nil {
|
||||
return fmt.Errorf("error when creating kube-proxy RBAC rules: %v", err)
|
||||
}
|
||||
|
||||
fmt.Println("[addons] Applied essential addon: kube-proxy")
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateServiceAccount creates the necessary serviceaccounts that kubeadm uses/might use, if they don't already exist.
|
||||
func CreateServiceAccount(client clientset.Interface) error {
|
||||
|
||||
return apiclient.CreateOrUpdateServiceAccount(client, &v1.ServiceAccount{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: KubeProxyServiceAccountName,
|
||||
Namespace: metav1.NamespaceSystem,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// CreateRBACRules creates the essential RBAC rules for a minimally set-up cluster
|
||||
func CreateRBACRules(client clientset.Interface) error {
|
||||
if err := createClusterRoleBindings(client); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func createKubeProxyAddon(configMapBytes, daemonSetbytes []byte, client clientset.Interface) error {
|
||||
kubeproxyConfigMap := &v1.ConfigMap{}
|
||||
if err := kuberuntime.DecodeInto(api.Codecs.UniversalDecoder(), configMapBytes, kubeproxyConfigMap); err != nil {
|
||||
return fmt.Errorf("unable to decode kube-proxy configmap %v", err)
|
||||
}
|
||||
|
||||
// Create the ConfigMap for kube-proxy or update it in case it already exists
|
||||
if err := apiclient.CreateOrUpdateConfigMap(client, kubeproxyConfigMap); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
kubeproxyDaemonSet := &extensions.DaemonSet{}
|
||||
if err := kuberuntime.DecodeInto(api.Codecs.UniversalDecoder(), daemonSetbytes, kubeproxyDaemonSet); err != nil {
|
||||
return fmt.Errorf("unable to decode kube-proxy daemonset %v", err)
|
||||
}
|
||||
|
||||
// Create the DaemonSet for kube-proxy or update it in case it already exists
|
||||
if err := apiclient.CreateOrUpdateDaemonSet(client, kubeproxyDaemonSet); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func createClusterRoleBindings(client clientset.Interface) error {
|
||||
return apiclient.CreateOrUpdateClusterRoleBinding(client, &rbac.ClusterRoleBinding{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "kubeadm:node-proxier",
|
||||
},
|
||||
RoleRef: rbac.RoleRef{
|
||||
APIGroup: rbac.GroupName,
|
||||
Kind: "ClusterRole",
|
||||
Name: KubeProxyClusterRoleName,
|
||||
},
|
||||
Subjects: []rbac.Subject{
|
||||
{
|
||||
Kind: rbac.ServiceAccountKind,
|
||||
Name: KubeProxyServiceAccountName,
|
||||
Namespace: metav1.NamespaceSystem,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func getClusterCIDR(podsubnet string) string {
|
||||
if len(podsubnet) == 0 {
|
||||
return ""
|
||||
}
|
||||
return "- --cluster-cidr=" + podsubnet
|
||||
}
|
||||
140
vendor/k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/proxy/proxy_test.go
generated
vendored
Normal file
140
vendor/k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/proxy/proxy_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
Copyright 2017 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 proxy
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
clientsetfake "k8s.io/client-go/kubernetes/fake"
|
||||
core "k8s.io/client-go/testing"
|
||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
)
|
||||
|
||||
func TestCreateServiceAccount(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
createErr error
|
||||
expectErr bool
|
||||
}{
|
||||
{
|
||||
"error-free case",
|
||||
nil,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"duplication errors should be ignored",
|
||||
apierrors.NewAlreadyExists(api.Resource(""), ""),
|
||||
false,
|
||||
},
|
||||
{
|
||||
"unexpected errors should be returned",
|
||||
apierrors.NewUnauthorized(""),
|
||||
true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
client := clientsetfake.NewSimpleClientset()
|
||||
if tc.createErr != nil {
|
||||
client.PrependReactor("create", "serviceaccounts", func(action core.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, tc.createErr
|
||||
})
|
||||
}
|
||||
|
||||
err := CreateServiceAccount(client)
|
||||
if tc.expectErr {
|
||||
if err == nil {
|
||||
t.Errorf("CreateServiceAccounts(%s) wanted err, got nil", tc.name)
|
||||
}
|
||||
continue
|
||||
} else if !tc.expectErr && err != nil {
|
||||
t.Errorf("CreateServiceAccounts(%s) returned unexpected err: %v", tc.name, err)
|
||||
}
|
||||
|
||||
wantResourcesCreated := 1
|
||||
if len(client.Actions()) != wantResourcesCreated {
|
||||
t.Errorf("CreateServiceAccounts(%s) should have made %d actions, but made %d", tc.name, wantResourcesCreated, len(client.Actions()))
|
||||
}
|
||||
|
||||
for _, action := range client.Actions() {
|
||||
if action.GetVerb() != "create" || action.GetResource().Resource != "serviceaccounts" {
|
||||
t.Errorf("CreateServiceAccounts(%s) called [%v %v], but wanted [create serviceaccounts]",
|
||||
tc.name, action.GetVerb(), action.GetResource().Resource)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetClusterCIDR(t *testing.T) {
|
||||
emptyClusterCIDR := getClusterCIDR("")
|
||||
if emptyClusterCIDR != "" {
|
||||
t.Errorf("Invalid format: %s", emptyClusterCIDR)
|
||||
}
|
||||
|
||||
clusterCIDR := getClusterCIDR("10.244.0.0/16")
|
||||
if clusterCIDR != "- --cluster-cidr=10.244.0.0/16" {
|
||||
t.Errorf("Invalid format: %s", clusterCIDR)
|
||||
}
|
||||
|
||||
clusterIPv6CIDR := getClusterCIDR("2001:db8::/64")
|
||||
if clusterIPv6CIDR != "- --cluster-cidr=2001:db8::/64" {
|
||||
t.Errorf("Invalid format: %s", clusterIPv6CIDR)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCompileManifests(t *testing.T) {
|
||||
var tests = []struct {
|
||||
manifest string
|
||||
data interface{}
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
manifest: KubeProxyConfigMap,
|
||||
data: struct{ MasterEndpoint string }{
|
||||
MasterEndpoint: "foo",
|
||||
},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
manifest: KubeProxyDaemonSet,
|
||||
data: struct{ ImageRepository, Arch, Version, ImageOverride, ClusterCIDR, MasterTaintKey, CloudTaintKey string }{
|
||||
ImageRepository: "foo",
|
||||
Arch: "foo",
|
||||
Version: "foo",
|
||||
ImageOverride: "foo",
|
||||
ClusterCIDR: "foo",
|
||||
MasterTaintKey: "foo",
|
||||
CloudTaintKey: "foo",
|
||||
},
|
||||
expected: true,
|
||||
},
|
||||
}
|
||||
for _, rt := range tests {
|
||||
_, actual := kubeadmutil.ParseTemplate(rt.manifest, rt.data)
|
||||
if (actual == nil) != rt.expected {
|
||||
t.Errorf(
|
||||
"failed CompileManifests:\n\texpected: %t\n\t actual: %t",
|
||||
rt.expected,
|
||||
(actual == nil),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
39
vendor/k8s.io/kubernetes/cmd/kubeadm/app/phases/apiconfig/BUILD
generated
vendored
Normal file
39
vendor/k8s.io/kubernetes/cmd/kubeadm/app/phases/apiconfig/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["clusterroles_test.go"],
|
||||
library = ":go_default_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["clusterroles.go"],
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/constants:go_default_library",
|
||||
"//pkg/util/version:go_default_library",
|
||||
"//vendor/k8s.io/api/rbac/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
69
vendor/k8s.io/kubernetes/cmd/kubeadm/app/phases/apiconfig/clusterroles.go
generated
vendored
Normal file
69
vendor/k8s.io/kubernetes/cmd/kubeadm/app/phases/apiconfig/clusterroles.go
generated
vendored
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
Copyright 2017 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 apiconfig
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
rbac "k8s.io/api/rbac/v1beta1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
"k8s.io/kubernetes/pkg/util/version"
|
||||
)
|
||||
|
||||
// CreateRBACRules creates the essential RBAC rules for a minimally set-up cluster
|
||||
// TODO: This function and phase package is DEPRECATED.
|
||||
// When the v1.9 cycle starts and deletePermissiveNodesBindingWhenUsingNodeAuthorization can be removed, this package will be removed with it.
|
||||
func CreateRBACRules(client clientset.Interface, k8sVersion *version.Version) error {
|
||||
if err := deletePermissiveNodesBindingWhenUsingNodeAuthorization(client, k8sVersion); err != nil {
|
||||
return fmt.Errorf("failed to remove the permissive 'system:nodes' Group Subject in the 'system:node' ClusterRoleBinding: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func deletePermissiveNodesBindingWhenUsingNodeAuthorization(client clientset.Interface, k8sVersion *version.Version) error {
|
||||
|
||||
// TODO: When the v1.9 cycle starts (targeting v1.9 at HEAD) and v1.8.0 is the minimum supported version, we can remove this function as the ClusterRoleBinding won't exist
|
||||
// or already have no such permissive subject
|
||||
nodesRoleBinding, err := client.RbacV1beta1().ClusterRoleBindings().Get(kubeadmconstants.NodesClusterRoleBinding, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
if apierrors.IsNotFound(err) {
|
||||
// Nothing to do; the RoleBinding doesn't exist
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
newSubjects := []rbac.Subject{}
|
||||
for _, subject := range nodesRoleBinding.Subjects {
|
||||
// Skip the subject that binds to the system:nodes group
|
||||
if subject.Name == kubeadmconstants.NodesGroup && subject.Kind == "Group" {
|
||||
continue
|
||||
}
|
||||
newSubjects = append(newSubjects, subject)
|
||||
}
|
||||
|
||||
nodesRoleBinding.Subjects = newSubjects
|
||||
|
||||
if _, err := client.RbacV1beta1().ClusterRoleBindings().Update(nodesRoleBinding); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue