Merge pull request #52251 from sbezverk/kubeadm_lint_cleanup

Automatic merge from submit-queue (batch tested with PRs 52251, 52540). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>..

kubeadm golint clean up

Cleaning up golint discovered issue for kubeadm

Fixes: https://github.com/kubernetes/kubeadm/issues/375
This commit is contained in:
Kubernetes Submit Queue 2017-09-25 07:19:53 -07:00 committed by GitHub
commit 7fa13044bb
36 changed files with 263 additions and 112 deletions

View File

@ -14,6 +14,10 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
// Package kubeadm is the package that contains the libraries that drive the kubeadm binary.
// kubeadm is responsible for handling a Kubernetes cluster's lifecycle.
// +k8s:deepcopy-gen=package,register
// +groupName=kubeadm.k8s.io
package kubeadm // import "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"

View File

@ -28,8 +28,10 @@ const GroupName = "kubeadm.k8s.io"
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal}
var (
// SchemeBuilder points to a list of functions added to Scheme.
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
AddToScheme = SchemeBuilder.AddToScheme
// AddToScheme applies all the stored functions to the scheme.
AddToScheme = SchemeBuilder.AddToScheme
)
// Kind takes an unqualified kind and returns a Group qualified GroupKind

View File

@ -22,6 +22,8 @@ import (
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// MasterConfiguration contains a list of elements which make up master's
// configuration object.
type MasterConfiguration struct {
metav1.TypeMeta
@ -59,6 +61,7 @@ type MasterConfiguration struct {
FeatureGates map[string]bool
}
// API struct contains elements of API server address.
type API struct {
// AdvertiseAddress sets the address for the API server to advertise.
AdvertiseAddress string
@ -66,18 +69,21 @@ type API struct {
BindPort int32
}
// TokenDiscovery contains elements needed for token discovery
type TokenDiscovery struct {
ID string
Secret string
Addresses []string
}
// Networking contains elements describing cluster's networking configuration
type Networking struct {
ServiceSubnet string
PodSubnet string
DNSDomain string
}
// Etcd contains elements describing Etcd configuration
type Etcd struct {
Endpoints []string
CAFile string
@ -91,6 +97,7 @@ type Etcd struct {
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// NodeConfiguration contains elements describing a particular node
type NodeConfiguration struct {
metav1.TypeMeta

View File

@ -26,21 +26,31 @@ import (
)
const (
DefaultServiceDNSDomain = "cluster.local"
DefaultServicesSubnet = "10.96.0.0/12"
DefaultKubernetesVersion = "stable-1.8"
DefaultAPIBindPort = 6443
// DefaultServiceDNSDomain defines default cluster-internal domain name for Services and Pods
DefaultServiceDNSDomain = "cluster.local"
// DefaultServicesSubnet defines default service subnet range
DefaultServicesSubnet = "10.96.0.0/12"
// DefaultKubernetesVersion defines default kubernetes version
DefaultKubernetesVersion = "stable-1.8"
// DefaultAPIBindPort defines default API port
DefaultAPIBindPort = 6443
// DefaultAuthorizationModes defines default authorization modes
DefaultAuthorizationModes = "Node,RBAC"
DefaultCACertPath = "/etc/kubernetes/pki/ca.crt"
DefaultCertificatesDir = "/etc/kubernetes/pki"
DefaultEtcdDataDir = "/var/lib/etcd"
DefaultImageRepository = "gcr.io/google_containers"
// DefaultCACertPath defines default location of CA certificate
DefaultCACertPath = "/etc/kubernetes/pki/ca.crt"
// DefaultCertificatesDir defines default certificate directory
DefaultCertificatesDir = "/etc/kubernetes/pki"
// DefaultEtcdDataDir defines default location of etcd
DefaultEtcdDataDir = "/var/lib/etcd"
// DefaultImageRepository defines default image registry
DefaultImageRepository = "gcr.io/google_containers"
)
func addDefaultingFuncs(scheme *runtime.Scheme) error {
return RegisterDefaults(scheme)
}
// SetDefaults_MasterConfiguration assigns default values to Master node
func SetDefaults_MasterConfiguration(obj *MasterConfiguration) {
if obj.KubernetesVersion == "" {
obj.KubernetesVersion = DefaultKubernetesVersion
@ -81,6 +91,7 @@ func SetDefaults_MasterConfiguration(obj *MasterConfiguration) {
}
}
// SetDefaults_NodeConfiguration assigns default values to a regular node
func SetDefaults_NodeConfiguration(obj *NodeConfiguration) {
if obj.CACertPath == "" {
obj.CACertPath = DefaultCACertPath

View File

@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
// Package v1alpha1 is the package that contains the libraries that drive the kubeadm binary.
// +k8s:defaulter-gen=TypeMeta
// +groupName=kubeadm.k8s.io
// +k8s:deepcopy-gen=package

View File

@ -31,9 +31,12 @@ var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha
var (
// TODO: move SchemeBuilder with zz_generated.deepcopy.go to k8s.io/api.
// localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes.
// SchemeBuilder points to a list of functions added to Scheme.
SchemeBuilder runtime.SchemeBuilder
localSchemeBuilder = &SchemeBuilder
AddToScheme = localSchemeBuilder.AddToScheme
// AddToScheme applies all the stored functions to the scheme.
AddToScheme = localSchemeBuilder.AddToScheme
)
func init() {

View File

@ -22,6 +22,8 @@ import (
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// MasterConfiguration contains a list of elements which make up master's
// configuration object.
type MasterConfiguration struct {
metav1.TypeMeta `json:",inline"`
@ -54,6 +56,7 @@ type MasterConfiguration struct {
FeatureGates map[string]bool `json:"featureGates,omitempty"`
}
// API struct contains elements of API server address.
type API struct {
// AdvertiseAddress sets the address for the API server to advertise.
AdvertiseAddress string `json:"advertiseAddress"`
@ -61,18 +64,21 @@ type API struct {
BindPort int32 `json:"bindPort"`
}
// TokenDiscovery contains elements needed for token discovery
type TokenDiscovery struct {
ID string `json:"id"`
Secret string `json:"secret"`
Addresses []string `json:"addresses"`
}
// Networking contains elements describing cluster's networking configuration
type Networking struct {
ServiceSubnet string `json:"serviceSubnet"`
PodSubnet string `json:"podSubnet"`
DNSDomain string `json:"dnsDomain"`
}
// Etcd contains elements describing Etcd configuration
type Etcd struct {
Endpoints []string `json:"endpoints"`
CAFile string `json:"caFile"`
@ -86,6 +92,7 @@ type Etcd struct {
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// NodeConfiguration contains elements describing a particular node
type NodeConfiguration struct {
metav1.TypeMeta `json:",inline"`

View File

@ -58,6 +58,7 @@ var requiredAuthzModes = []string{
authzmodes.ModeNode,
}
// ValidateMasterConfiguration validates master configuration and collects all encountered errors
func ValidateMasterConfiguration(c *kubeadm.MasterConfiguration) field.ErrorList {
allErrs := field.ErrorList{}
allErrs = append(allErrs, ValidateCloudProvider(c.CloudProvider, field.NewPath("cloudprovider"))...)
@ -72,6 +73,7 @@ func ValidateMasterConfiguration(c *kubeadm.MasterConfiguration) field.ErrorList
return allErrs
}
// ValidateNodeConfiguration validates node configuration and collects all encountered errors
func ValidateNodeConfiguration(c *kubeadm.NodeConfiguration) field.ErrorList {
allErrs := field.ErrorList{}
allErrs = append(allErrs, ValidateDiscovery(c, field.NewPath("discovery"))...)
@ -82,10 +84,10 @@ func ValidateNodeConfiguration(c *kubeadm.NodeConfiguration) field.ErrorList {
return allErrs
}
// ValidateAuthorizationModes validates authorization modes and collects all encountered errors
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"))
@ -105,6 +107,7 @@ func ValidateAuthorizationModes(authzModes []string, fldPath *field.Path) field.
return allErrs
}
// ValidateDiscovery validates discovery related configuration and collects all encountered errors
func ValidateDiscovery(c *kubeadm.NodeConfiguration, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if len(c.DiscoveryToken) != 0 {
@ -123,10 +126,10 @@ func ValidateDiscovery(c *kubeadm.NodeConfiguration, fldPath *field.Path) field.
if len(c.DiscoveryFile) != 0 {
allErrs = append(allErrs, ValidateDiscoveryFile(c.DiscoveryFile, fldPath)...)
}
return allErrs
}
// ValidateArgSelection validates discovery related configuration and collects all encountered errors
func ValidateArgSelection(cfg *kubeadm.NodeConfiguration, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if len(cfg.DiscoveryToken) != 0 && len(cfg.DiscoveryFile) != 0 {
@ -156,6 +159,7 @@ func ValidateArgSelection(cfg *kubeadm.NodeConfiguration, fldPath *field.Path) f
return allErrs
}
// ValidateJoinDiscoveryTokenAPIServer validates discovery token for API server
func ValidateJoinDiscoveryTokenAPIServer(c *kubeadm.NodeConfiguration, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
for _, m := range c.DiscoveryTokenAPIServers {
@ -167,6 +171,7 @@ func ValidateJoinDiscoveryTokenAPIServer(c *kubeadm.NodeConfiguration, fldPath *
return allErrs
}
// ValidateDiscoveryFile validates location of a discovery file
func ValidateDiscoveryFile(discoveryFile string, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
u, err := url.Parse(discoveryFile)
@ -189,6 +194,7 @@ func ValidateDiscoveryFile(discoveryFile string, fldPath *field.Path) field.Erro
return allErrs
}
// ValidateToken validates token
func ValidateToken(t string, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
@ -203,6 +209,7 @@ func ValidateToken(t string, fldPath *field.Path) field.ErrorList {
return allErrs
}
// ValidateAPIServerCertSANs validates alternative names
func ValidateAPIServerCertSANs(altnames []string, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
for _, altname := range altnames {
@ -213,6 +220,7 @@ func ValidateAPIServerCertSANs(altnames []string, fldPath *field.Path) field.Err
return allErrs
}
// ValidateIPFromString validates ip address
func ValidateIPFromString(ipaddr string, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if net.ParseIP(ipaddr) == nil {
@ -221,6 +229,7 @@ func ValidateIPFromString(ipaddr string, fldPath *field.Path) field.ErrorList {
return allErrs
}
// ValidateIPNetFromString validates network portion of ip address
func ValidateIPNetFromString(subnet string, minAddrs int64, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
_, svcSubnet, err := net.ParseCIDR(subnet)
@ -235,6 +244,7 @@ func ValidateIPNetFromString(subnet string, minAddrs int64, fldPath *field.Path)
return allErrs
}
// ValidateNetworking validates networking configuration
func ValidateNetworking(c *kubeadm.Networking, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
allErrs = append(allErrs, apivalidation.ValidateDNS1123Subdomain(c.DNSDomain, field.NewPath("dns-domain"))...)
@ -245,6 +255,7 @@ func ValidateNetworking(c *kubeadm.Networking, fldPath *field.Path) field.ErrorL
return allErrs
}
// ValidateAbsolutePath validates whether provided path is absolute or not
func ValidateAbsolutePath(path string, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if !filepath.IsAbs(path) {
@ -253,6 +264,7 @@ func ValidateAbsolutePath(path string, fldPath *field.Path) field.ErrorList {
return allErrs
}
// ValidateNodeName validates the name of a node
func ValidateNodeName(nodename string, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if node.GetHostname(nodename) != nodename {
@ -261,6 +273,7 @@ func ValidateNodeName(nodename string, fldPath *field.Path) field.ErrorList {
return allErrs
}
// ValidateCloudProvider validates if cloud provider is supported
func ValidateCloudProvider(provider string, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if len(provider) == 0 {
@ -275,6 +288,7 @@ func ValidateCloudProvider(provider string, fldPath *field.Path) field.ErrorList
return allErrs
}
// ValidateMixedArguments validates passed arguments
func ValidateMixedArguments(flag *pflag.FlagSet) error {
// If --config isn't set, we have nothing to validate
if !flag.Changed("config") {
@ -296,6 +310,7 @@ func ValidateMixedArguments(flag *pflag.FlagSet) error {
return nil
}
// ValidateFeatureGates validates provided feature gates
func ValidateFeatureGates(featureGates map[string]bool, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
validFeatures := features.Keys(features.InitFeatureGates)
@ -311,6 +326,7 @@ func ValidateFeatureGates(featureGates map[string]bool, fldPath *field.Path) fie
return allErrs
}
// ValidateAPIEndpoint validates API server's endpoint
func ValidateAPIEndpoint(c *kubeadm.MasterConfiguration, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}

View File

@ -410,7 +410,6 @@ func TestValidateMixedArguments(t *testing.T) {
}
var cfgPath string
for _, rt := range tests {
f := pflag.NewFlagSet("test", pflag.ContinueOnError)
if f.Parsed() {

View File

@ -27,6 +27,7 @@ import (
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/upgrade"
)
// NewKubeadmCommand return cobra.Command to run kubeadm command
func NewKubeadmCommand(_ io.Reader, out, err io.Writer) *cobra.Command {
cmds := &cobra.Command{
Use: "kubeadm",

View File

@ -45,7 +45,7 @@ const defaultBoilerPlate = `
`
var (
completion_long = dedent.Dedent(`
completionLong = 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
@ -63,7 +63,7 @@ var (
Note for zsh users: [1] zsh completions are only supported in versions of zsh >= 5.2`)
completion_example = dedent.Dedent(`
completionExample = 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
@ -82,23 +82,24 @@ var (
)
var (
completion_shells = map[string]func(out io.Writer, cmd *cobra.Command) error{
completionShells = map[string]func(out io.Writer, cmd *cobra.Command) error{
"bash": runCompletionBash,
"zsh": runCompletionZsh,
}
)
// NewCmdCompletion return command for executing "kubeadm completion" command
func NewCmdCompletion(out io.Writer, boilerPlate string) *cobra.Command {
shells := []string{}
for s := range completion_shells {
for s := range completionShells {
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,
Long: completionLong,
Example: completionExample,
Run: func(cmd *cobra.Command, args []string) {
err := RunCompletion(out, boilerPlate, cmd, args)
kubeadmutil.CheckErr(err)
@ -109,16 +110,17 @@ func NewCmdCompletion(out io.Writer, boilerPlate string) *cobra.Command {
return cmd
}
// RunCompletion checks given arguments and executes command
func RunCompletion(out io.Writer, boilerPlate string, cmd *cobra.Command, args []string) error {
if len(args) == 0 {
return fmt.Errorf("shell not specified.")
return fmt.Errorf("shell not specified")
}
if len(args) > 1 {
return fmt.Errorf("too many arguments. expected only the shell type.")
return fmt.Errorf("too many arguments. expected only the shell type")
}
run, found := completion_shells[args[0]]
run, found := completionShells[args[0]]
if !found {
return fmt.Errorf("unsupported shell type %q.", args[0])
return fmt.Errorf("unsupported shell type %q", args[0])
}
if len(boilerPlate) == 0 {
@ -135,7 +137,7 @@ func runCompletionBash(out io.Writer, kubeadm *cobra.Command) error {
}
func runCompletionZsh(out io.Writer, kubeadm *cobra.Command) error {
zsh_initialization := `
zshInitialization := `
__kubeadm_bash_source() {
alias shopt=':'
alias _expand=_bash_expand
@ -276,18 +278,18 @@ __kubeadm_convert_bash_to_zsh() {
-e "s/\\\$(type${RWORD}/\$(__kubeadm_type/g" \
<<'BASH_COMPLETION_EOF'
`
out.Write([]byte(zsh_initialization))
out.Write([]byte(zshInitialization))
buf := new(bytes.Buffer)
kubeadm.GenBashCompletion(buf)
out.Write(buf.Bytes())
zsh_tail := `
zshTail := `
BASH_COMPLETION_EOF
}
__kubeadm_bash_source <(__kubeadm_convert_bash_to_zsh)
`
out.Write([]byte(zsh_tail))
out.Write([]byte(zshTail))
return nil
}

View File

@ -36,6 +36,7 @@ import (
"k8s.io/kubernetes/pkg/api"
)
// NewCmdConfig returns cobra.Command for "kubeadm config" command
func NewCmdConfig(out io.Writer) *cobra.Command {
var kubeConfigFile string
@ -64,6 +65,7 @@ func NewCmdConfig(out io.Writer) *cobra.Command {
return cmd
}
// NewCmdConfigUpload returs cobra.Command for "kubeadm config upload" command
func NewCmdConfigUpload(out io.Writer, kubeConfigFile *string) *cobra.Command {
cmd := &cobra.Command{
Use: "upload",
@ -76,6 +78,7 @@ func NewCmdConfigUpload(out io.Writer, kubeConfigFile *string) *cobra.Command {
return cmd
}
// NewCmdConfigView returs cobra.Command for "kubeadm config view" command
func NewCmdConfigView(out io.Writer, kubeConfigFile *string) *cobra.Command {
return &cobra.Command{
Use: "view",
@ -95,6 +98,8 @@ func NewCmdConfigView(out io.Writer, kubeConfigFile *string) *cobra.Command {
}
}
// NewCmdConfigUploadFromFile verifies given kubernetes config file and returs cobra.Command for
// "kubeadm config upload from-file" command
func NewCmdConfigUploadFromFile(out io.Writer, kubeConfigFile *string) *cobra.Command {
var cfgPath string
cmd := &cobra.Command{
@ -126,6 +131,7 @@ func NewCmdConfigUploadFromFile(out io.Writer, kubeConfigFile *string) *cobra.Co
return cmd
}
// NewCmdConfigUploadFromFlags returs cobra.Command for "kubeadm config upload from-flags" command
func NewCmdConfigUploadFromFlags(out io.Writer, kubeConfigFile *string) *cobra.Command {
cfg := &kubeadmapiext.MasterConfiguration{}
api.Scheme.Default(cfg)

View File

@ -211,6 +211,7 @@ func AddInitOtherFlags(flagSet *flag.FlagSet, cfgPath *string, skipPreFlight, sk
)
}
// NewInit validates given arguments and instantiates Init struct with provided information.
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.")
@ -256,6 +257,7 @@ func NewInit(cfgPath string, cfg *kubeadmapi.MasterConfiguration, skipPreFlight,
return &Init{cfg: cfg, skipTokenPrint: skipTokenPrint, dryRun: dryRun}, nil
}
// Init defines struct used by "kubeadm init" command
type Init struct {
cfg *kubeadmapi.MasterConfiguration
skipTokenPrint bool

View File

@ -154,10 +154,12 @@ func NewCmdJoin(out io.Writer) *cobra.Command {
return cmd
}
// Join defines struct used by kubeadm join command
type Join struct {
cfg *kubeadmapi.NodeConfiguration
}
// NewJoin instantiates Join struct with given arguments
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.")
@ -192,6 +194,7 @@ func NewJoin(cfgPath string, args []string, cfg *kubeadmapi.NodeConfiguration, s
return &Join{cfg: cfg}, nil
}
// Validate validates mixed arguments passed to cobra.Command
func (j *Join) Validate(cmd *cobra.Command) error {
if err := validation.ValidateMixedArguments(cmd.PersistentFlags()); err != nil {
return err
@ -206,7 +209,7 @@ func (j *Join) Run(out io.Writer) error {
return err
}
client, err := kubeconfigutil.KubeConfigToClientSet(cfg)
client, err := kubeconfigutil.ToClientSet(cfg)
if err != nil {
return err
}

View File

@ -110,7 +110,7 @@ func NewSubCmdNodeBootstrapTokenPostCSRs(kubeConfigFile *string) *cobra.Command
return cmd
}
// NewSubCmdNodeBootstrapToken returns the Cobra command for running the allow-auto-approve sub-phase
// NewSubCmdNodeBootstrapTokenAutoApprove 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",

View File

@ -24,6 +24,7 @@ import (
"k8s.io/kubernetes/cmd/kubeadm/app/preflight"
)
// NewCmdPreFlight calls cobra.Command for preflight checks
func NewCmdPreFlight() *cobra.Command {
cmd := &cobra.Command{
Use: "preflight",
@ -36,6 +37,7 @@ func NewCmdPreFlight() *cobra.Command {
return cmd
}
// NewCmdPreFlightMaster calls cobra.Command for master preflight checks
func NewCmdPreFlightMaster() *cobra.Command {
cmd := &cobra.Command{
Use: "master",
@ -49,6 +51,7 @@ func NewCmdPreFlightMaster() *cobra.Command {
return cmd
}
// NewCmdPreFlightNode calls cobra.Command for node preflight checks
func NewCmdPreFlightNode() *cobra.Command {
cmd := &cobra.Command{
Use: "node",

View File

@ -59,10 +59,12 @@ func NewCmdReset(out io.Writer) *cobra.Command {
return cmd
}
// Reset defines struct used for kubeadm reset command
type Reset struct {
certsDir string
}
// NewReset instantiate Reset struct
func NewReset(skipPreFlight bool, certsDir string) (*Reset, error) {
if !skipPreFlight {
fmt.Println("[preflight] Running pre-flight checks")

View File

@ -46,6 +46,7 @@ import (
"k8s.io/kubernetes/pkg/printers"
)
// NewCmdToken returns cobra.Command for token management
func NewCmdToken(out io.Writer, errW io.Writer) *cobra.Command {
var kubeConfigFile string
@ -168,6 +169,7 @@ func NewCmdToken(out io.Writer, errW io.Writer) *cobra.Command {
return tokenCmd
}
// NewCmdTokenGenerate returns cobra.Command to generate new token
func NewCmdTokenGenerate(out io.Writer) *cobra.Command {
return &cobra.Command{
Use: "generate",
@ -260,14 +262,14 @@ func RunListTokens(out io.Writer, errW io.Writer, client clientset.Interface) er
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 {
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) {
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
}
@ -277,7 +279,7 @@ func RunListTokens(out io.Writer, errW io.Writer, client clientset.Interface) er
fmt.Fprintf(errW, "bootstrap token has no token-secret data: %s\n", secret.Name)
continue
}
td := &kubeadmapi.TokenDiscovery{ID: tokenId, Secret: tokenSecret}
td := &kubeadmapi.TokenDiscovery{ID: tokenID, Secret: tokenSecret}
// Expiration time is optional, if not specified this implies the token
// never expires.
@ -328,20 +330,20 @@ func RunListTokens(out io.Writer, errW io.Writer, client clientset.Interface) er
}
// RunDeleteToken removes a bootstrap token from the server.
func RunDeleteToken(out io.Writer, client clientset.Interface, tokenIdOrToken string) error {
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)
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)
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)
fmt.Fprintf(out, "bootstrap token with id %q deleted\n", tokenID)
return nil
}

View File

@ -36,6 +36,7 @@ type Version struct {
ClientVersion *apimachineryversion.Info `json:"clientVersion"`
}
// NewCmdVersion provides the version information of kubeadm.
func NewCmdVersion(out io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "version",
@ -49,6 +50,8 @@ func NewCmdVersion(out io.Writer) *cobra.Command {
return cmd
}
// RunVersion provides the version information of kubeadm in format depending on an arguments
// specified in cobra.Command.
func RunVersion(out io.Writer, cmd *cobra.Command) error {
clientVersion := version.Get()
v := Version{

View File

@ -32,48 +32,87 @@ import (
var KubernetesDir = "/etc/kubernetes"
const (
// ManifestsSubDirName defines directory name to store manifests
ManifestsSubDirName = "manifests"
TempDirForKubeadm = "/etc/kubernetes/tmp"
// TempDirForKubeadm defines temporary directory for kubeadm
TempDirForKubeadm = "/etc/kubernetes/tmp"
// CACertAndKeyBaseName defines certificate authority base name
CACertAndKeyBaseName = "ca"
CACertName = "ca.crt"
CAKeyName = "ca.key"
// CACertName defines certificate name
CACertName = "ca.crt"
// CAKeyName defines certificate name
CAKeyName = "ca.key"
// APIServerCertAndKeyBaseName defines API's server certificate and key base name
APIServerCertAndKeyBaseName = "apiserver"
APIServerCertName = "apiserver.crt"
APIServerKeyName = "apiserver.key"
APIServerCertCommonName = "kube-apiserver" //used as subject.commonname attribute (CN)
// APIServerCertName defines API's server certificate name
APIServerCertName = "apiserver.crt"
// APIServerKeyName defines API's server key name
APIServerKeyName = "apiserver.key"
// APIServerCertCommonName defines API's server certificate common name (CN)
APIServerCertCommonName = "kube-apiserver"
// APIServerKubeletClientCertAndKeyBaseName defines kubelet client certificate and key base name
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)
// APIServerKubeletClientCertName defines kubelet client certificate name
APIServerKubeletClientCertName = "apiserver-kubelet-client.crt"
// APIServerKubeletClientKeyName defines kubelet client key name
APIServerKubeletClientKeyName = "apiserver-kubelet-client.key"
// APIServerKubeletClientCertCommonName defines kubelet client certificate common name (CN)
APIServerKubeletClientCertCommonName = "kube-apiserver-kubelet-client"
ServiceAccountKeyBaseName = "sa"
ServiceAccountPublicKeyName = "sa.pub"
// ServiceAccountKeyBaseName defines SA key base name
ServiceAccountKeyBaseName = "sa"
// ServiceAccountPublicKeyName defines SA public key base name
ServiceAccountPublicKeyName = "sa.pub"
// ServiceAccountPrivateKeyName defines SA private key base name
ServiceAccountPrivateKeyName = "sa.key"
// FrontProxyCACertAndKeyBaseName defines front proxy CA certificate and key base name
FrontProxyCACertAndKeyBaseName = "front-proxy-ca"
FrontProxyCACertName = "front-proxy-ca.crt"
FrontProxyCAKeyName = "front-proxy-ca.key"
// FrontProxyCACertName defines front proxy CA certificate name
FrontProxyCACertName = "front-proxy-ca.crt"
// FrontProxyCAKeyName defaines front proxy CA key name
FrontProxyCAKeyName = "front-proxy-ca.key"
// FrontProxyClientCertAndKeyBaseName defines front proxy certificate and key base name
FrontProxyClientCertAndKeyBaseName = "front-proxy-client"
FrontProxyClientCertName = "front-proxy-client.crt"
FrontProxyClientKeyName = "front-proxy-client.key"
FrontProxyClientCertCommonName = "front-proxy-client" //used as subject.commonname attribute (CN)
// FrontProxyClientCertName defines front proxy certificate name
FrontProxyClientCertName = "front-proxy-client.crt"
// FrontProxyClientKeyName defines front proxy key name
FrontProxyClientKeyName = "front-proxy-client.key"
// FrontProxyClientCertCommonName defines front proxy certificate common name
FrontProxyClientCertCommonName = "front-proxy-client" //used as subject.commonname attribute (CN)
AdminKubeConfigFileName = "admin.conf"
KubeletBootstrapKubeConfigFileName = "bootstrap-kubelet.conf"
KubeletKubeConfigFileName = "kubelet.conf"
// AdminKubeConfigFileName defines name for the KubeConfig aimed to be used by the superuser/admin of the cluster
AdminKubeConfigFileName = "admin.conf"
// KubeletBootstrapKubeConfigFileName defines the file name for the KubeConfig that the kubelet will use to do
// the TLS bootstrap to get itself an unique credential
KubeletBootstrapKubeConfigFileName = "bootstrap-kubelet.conf"
// KubeletKubeConfigFileName defines the file name for the KubeConfig that the master kubelet will use for talking
// to the API server
KubeletKubeConfigFileName = "kubelet.conf"
// ControllerManagerKubeConfigFileName defines the file name for the controller manager's KubeConfig file
ControllerManagerKubeConfigFileName = "controller-manager.conf"
SchedulerKubeConfigFileName = "scheduler.conf"
// SchedulerKubeConfigFileName defines the file name for the scheduler's KubeConfig file
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"
// ControllerManagerUser defines the well-known user the controller-manager should be authenticated as
ControllerManagerUser = "system:kube-controller-manager"
// SchedulerUser defines the well-known user the scheduler should be authenticated as
SchedulerUser = "system:kube-scheduler"
// MastersGroup defines the well-known group for the apiservers. This group is also superuser by default
// (i.e. bound to the cluster-admin ClusterRole)
MastersGroup = "system:masters"
// NodesGroup defines the well-known group for all nodes.
NodesGroup = "system:nodes"
// NodesClusterRoleBinding defines the well-known ClusterRoleBinding which binds the too permissive system:node
// ClusterRole to the system:nodes group. Since kubeadm is using the Node Authorizer, this ClusterRoleBinding's
// system:nodes group subject is removed if present.
NodesClusterRoleBinding = "system:node"
// APICallRetryInterval defines how long kubeadm should wait before retrying a failed API operation
@ -83,7 +122,7 @@ const (
// 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.
// MinimumAddressesInServiceSubnet defines 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
@ -107,11 +146,16 @@ const (
// DefaultEtcdVersion indicates the default etcd version that kubeadm uses
DefaultEtcdVersion = "3.0.17"
Etcd = "etcd"
KubeAPIServer = "kube-apiserver"
// Etcd defines variable used internally when referring to etcd component
Etcd = "etcd"
// KubeAPIServer defines variable used internally when referring to kube-apiserver component
KubeAPIServer = "kube-apiserver"
// KubeControllerManager defines variable used internally when referring to kube-controller-manager component
KubeControllerManager = "kube-controller-manager"
KubeScheduler = "kube-scheduler"
KubeProxy = "kube-proxy"
// KubeScheduler defines variable used internally when referring to kube-scheduler component
KubeScheduler = "kube-scheduler"
// KubeProxy defines variable used internally when referring to kube-proxy component
KubeProxy = "kube-proxy"
// SelfHostingPrefix describes the prefix workloads that are self-hosted by kubeadm has
SelfHostingPrefix = "self-hosted-"
@ -146,7 +190,9 @@ var (
Effect: v1.TaintEffectNoSchedule,
}
AuthorizationPolicyPath = filepath.Join(KubernetesDir, "abac_policy.json")
// AuthorizationPolicyPath defines the supported location of authorization policy file
AuthorizationPolicyPath = filepath.Join(KubernetesDir, "abac_policy.json")
// AuthorizationWebhookConfigPath defines the supported location of webhook config file
AuthorizationWebhookConfigPath = filepath.Join(KubernetesDir, "webhook_authz.conf")
// DefaultTokenUsages specifies the default functions a token will get

View File

@ -28,6 +28,7 @@ import (
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
)
// TokenUser defines token user
const TokenUser = "tls-bootstrap-token-user"
// For returns a KubeConfig object that can be used for doing the TLS Bootstrap with the right credentials
@ -60,7 +61,7 @@ func GetValidatedClusterInfoObject(cfg *kubeadmapi.NodeConfiguration) (*clientcm
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.")
return nil, fmt.Errorf("couldn't find a valid discovery configuration")
}
}

View File

@ -62,7 +62,7 @@ func ValidateClusterInfo(clusterinfo *clientcmdapi.Config) (*clientcmdapi.Cluste
defaultCluster.CertificateAuthorityData,
)
client, err := kubeconfigutil.KubeConfigToClientSet(configFromClusterInfo)
client, err := kubeconfigutil.ToClientSet(configFromClusterInfo)
if err != nil {
return nil, err
}
@ -79,10 +79,9 @@ func ValidateClusterInfo(clusterinfo *clientcmdapi.Config) (*clientcmdapi.Cluste
// 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
}
fmt.Printf("[discovery] Failed to validate the API Server's identity, will try again: [%v]\n", err)
return false, nil
}
return true, nil
})

View File

@ -36,13 +36,14 @@ import (
"k8s.io/kubernetes/pkg/controller/bootstrap"
)
// BootstrapUser defines bootstrap user name
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)
tokenID, tokenSecret, err := tokenutil.ParseToken(discoveryToken)
if err != nil {
return nil, err
}
@ -61,7 +62,7 @@ func RetrieveValidatedClusterInfo(discoveryToken string, tokenAPIServers, rootCA
insecureBootstrapConfig := buildInsecureBootstrapKubeConfig(endpoint)
clusterName := insecureBootstrapConfig.Contexts[insecureBootstrapConfig.CurrentContext].Cluster
insecureClient, err := kubeconfigutil.KubeConfigToClientSet(insecureBootstrapConfig)
insecureClient, err := kubeconfigutil.ToClientSet(insecureBootstrapConfig)
if err != nil {
return nil, err
}
@ -85,11 +86,11 @@ func RetrieveValidatedClusterInfo(discoveryToken string, tokenAPIServers, rootCA
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]
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)
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) {
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)
@ -126,7 +127,7 @@ func RetrieveValidatedClusterInfo(discoveryToken string, tokenAPIServers, rootCA
// 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)
secureClient, err := kubeconfigutil.ToClientSet(secureBootstrapConfig)
if err != nil {
return nil, err
}

View File

@ -24,6 +24,7 @@ import (
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
)
// GetCoreImage generates and returns the image for the core Kubernetes components or returns overrideImage if specified
func GetCoreImage(image, repoPrefix, k8sVersion, overrideImage string) string {
if overrideImage != "" {
return overrideImage

View File

@ -25,6 +25,7 @@ import (
"k8s.io/kubernetes/cmd/kubeadm/app/cmd"
)
// Run creates and executes new kubeadm command
func Run() error {
// We do not want these flags to show up in --help
pflag.CommandLine.MarkHidden("google-json-key")

View File

@ -31,7 +31,7 @@ const CSRContextAndUser = "kubelet-csr"
// PerformTLSBootstrap executes a node certificate signing request.
func PerformTLSBootstrap(cfg *clientcmdapi.Config, hostName string) error {
client, err := kubeconfigutil.KubeConfigToClientSet(cfg)
client, err := kubeconfigutil.ToClientSet(cfg)
if err != nil {
return err
}

View File

@ -27,6 +27,7 @@ import (
certutil "k8s.io/client-go/util/cert"
)
// NewCertificateAuthority creates new certificate and private key for the certificate authority
func NewCertificateAuthority() (*x509.Certificate, *rsa.PrivateKey, error) {
key, err := certutil.NewPrivateKey()
if err != nil {
@ -44,6 +45,7 @@ func NewCertificateAuthority() (*x509.Certificate, *rsa.PrivateKey, error) {
return cert, key, nil
}
// NewCertAndKey creates new certificate and key by passing the certificate authority certificate and key
func NewCertAndKey(caCert *x509.Certificate, caKey *rsa.PrivateKey, config certutil.Config) (*x509.Certificate, *rsa.PrivateKey, error) {
key, err := certutil.NewPrivateKey()
if err != nil {
@ -68,6 +70,7 @@ func HasServerAuth(cert *x509.Certificate) bool {
return false
}
// WriteCertAndKey stores certificate and key at the specified location
func WriteCertAndKey(pkiPath string, name string, cert *x509.Certificate, key *rsa.PrivateKey) error {
if err := WriteKey(pkiPath, name, key); err != nil {
return err
@ -80,6 +83,7 @@ func WriteCertAndKey(pkiPath string, name string, cert *x509.Certificate, key *r
return nil
}
// WriteCert stores the given certificate at the given location
func WriteCert(pkiPath, name string, cert *x509.Certificate) error {
if cert == nil {
return fmt.Errorf("certificate cannot be nil when writing to file")
@ -93,6 +97,7 @@ func WriteCert(pkiPath, name string, cert *x509.Certificate) error {
return nil
}
// WriteKey stores the given key at the given location
func WriteKey(pkiPath, name string, key *rsa.PrivateKey) error {
if key == nil {
return fmt.Errorf("private key cannot be nil when writing to file")
@ -106,6 +111,7 @@ func WriteKey(pkiPath, name string, key *rsa.PrivateKey) error {
return nil
}
// WritePublicKey stores the given public key at the given location
func WritePublicKey(pkiPath, name string, key *rsa.PublicKey) error {
if key == nil {
return fmt.Errorf("public key cannot be nil when writing to file")

View File

@ -64,6 +64,7 @@ var (
minExternalEtcdVersion = semver.MustParse(kubeadmconstants.MinExternalEtcdVersion)
)
// Error defines struct for communicating error messages generated by preflight checks
type Error struct {
Msg string
}
@ -86,6 +87,7 @@ type ServiceCheck struct {
CheckIfActive bool
}
// Check validates if the service is enabled and active.
func (sc ServiceCheck) Check() (warnings, errors []error) {
initSystem, err := initsystem.GetInitSystem()
if err != nil {
@ -114,11 +116,13 @@ func (sc ServiceCheck) Check() (warnings, errors []error) {
return warnings, errors
}
// FirewalldCheck checks if firewalld is enabled or active, and if so outputs a warning.
// FirewalldCheck checks if firewalld is enabled or active. If it is, warn the user that there may be problems
// if no actions are taken.
type FirewalldCheck struct {
ports []int
}
// Check validates if the firewall is enabled and active.
func (fc FirewalldCheck) Check() (warnings, errors []error) {
initSystem, err := initsystem.GetInitSystem()
if err != nil {
@ -145,6 +149,7 @@ type PortOpenCheck struct {
port int
}
// Check validates if the particular port is available.
func (poc PortOpenCheck) Check() (warnings, errors []error) {
errors = []error{}
ln, err := net.Listen("tcp", fmt.Sprintf(":%d", poc.port))
@ -161,6 +166,7 @@ func (poc PortOpenCheck) Check() (warnings, errors []error) {
// IsRootCheck verifies user is root
type IsRootCheck struct{}
// Check validates if an user has root privileges.
func (irc IsRootCheck) Check() (warnings, errors []error) {
errors = []error{}
if os.Getuid() != 0 {
@ -175,6 +181,7 @@ type DirAvailableCheck struct {
Path string
}
// Check validates if a directory does not exist or empty.
func (dac DirAvailableCheck) Check() (warnings, errors []error) {
errors = []error{}
// If it doesn't exist we are good:
@ -202,6 +209,7 @@ type FileAvailableCheck struct {
Path string
}
// Check validates if the given file does not already exist.
func (fac FileAvailableCheck) Check() (warnings, errors []error) {
errors = []error{}
if _, err := os.Stat(fac.Path); err == nil {
@ -215,6 +223,7 @@ type FileExistingCheck struct {
Path string
}
// Check validates if the given file already exists.
func (fac FileExistingCheck) Check() (warnings, errors []error) {
errors = []error{}
if _, err := os.Stat(fac.Path); err != nil {
@ -229,6 +238,7 @@ type FileContentCheck struct {
Content []byte
}
// Check validates if the given file contains the given content.
func (fcc FileContentCheck) Check() (warnings, errors []error) {
f, err := os.Open(fcc.Path)
if err != nil {
@ -251,12 +261,13 @@ func (fcc FileContentCheck) Check() (warnings, errors []error) {
}
// InPathCheck checks if the given executable is present in the path
// InPathCheck checks if the given executable is present in $PATH
type InPathCheck struct {
executable string
mandatory bool
}
// Check validates if the given executable is present in the path.
func (ipc InPathCheck) Check() (warnings, errors []error) {
_, err := exec.LookPath(ipc.executable)
if err != nil {
@ -276,6 +287,7 @@ type HostnameCheck struct {
nodeName string
}
// Check validates if hostname match dns sub domain regex.
func (hc HostnameCheck) Check() (warnings, errors []error) {
errors = []error{}
warnings = []error{}
@ -300,6 +312,7 @@ type HTTPProxyCheck struct {
Port int
}
// Check validates http connectivity type, direct or via proxy.
func (hst HTTPProxyCheck) Check() (warnings, errors []error) {
url := fmt.Sprintf("%s://%s:%d", hst.Proto, hst.Host, hst.Port)
@ -326,6 +339,7 @@ type ExtraArgsCheck struct {
SchedulerExtraArgs map[string]string
}
// Check validates additional arguments of the control plane components.
func (eac ExtraArgsCheck) Check() (warnings, errors []error) {
argsCheck := func(name string, args map[string]string, f *pflag.FlagSet) []error {
errs := []error{}
@ -359,8 +373,10 @@ func (eac ExtraArgsCheck) Check() (warnings, errors []error) {
return warnings, nil
}
// SystemVerificationCheck defines struct used for for running the system verification node check in test/e2e_node/system
type SystemVerificationCheck struct{}
// Check runs all individual checks
func (sysver SystemVerificationCheck) Check() (warnings, errors []error) {
// Create a buffered writer and choose a quite large value (1M) and suppose the output from the system verification test won't exceed the limit
// Run the system verification check, but write to out buffered writer instead of stdout
@ -397,11 +413,13 @@ func (sysver SystemVerificationCheck) Check() (warnings, errors []error) {
return warns, nil
}
// KubernetesVersionCheck validates kubernetes and kubeadm versions
type KubernetesVersionCheck struct {
KubeadmVersion string
KubernetesVersion string
}
// Check validates kubernetes and kubeadm versions
func (kubever KubernetesVersionCheck) Check() (warnings, errors []error) {
// Skip this check for "super-custom builds", where apimachinery/the overall codebase version is not set.
@ -434,6 +452,7 @@ func (kubever KubernetesVersionCheck) Check() (warnings, errors []error) {
// SwapCheck warns if swap is enabled
type SwapCheck struct{}
// Check validates whether swap is enabled or not
func (swc SwapCheck) Check() (warnings, errors []error) {
f, err := os.Open("/proc/swaps")
if err != nil {
@ -451,7 +470,7 @@ func (swc SwapCheck) Check() (warnings, errors []error) {
}
if len(buf) > 1 {
return []error{fmt.Errorf("Running with swap on is not supported. Please disable swap or set kubelet's --fail-swap-on flag to false.")}, nil
return []error{fmt.Errorf("running with swap on is not supported. Please disable swap or set kubelet's --fail-swap-on flag to false")}, nil
}
return nil, nil
@ -467,6 +486,7 @@ type ExternalEtcdVersionCheck struct {
Etcd kubeadmapi.Etcd
}
// Check validates external etcd version
func (evc ExternalEtcdVersionCheck) Check() (warnings, errors []error) {
var config *tls.Config
var err error
@ -549,6 +569,7 @@ func (evc ExternalEtcdVersionCheck) configCertAndKey(config *tls.Config) (*tls.C
}
return config, nil
}
func (evc ExternalEtcdVersionCheck) getHTTPClient(config *tls.Config) *http.Client {
if config != nil {
transport := &http.Transport{
@ -561,6 +582,7 @@ func (evc ExternalEtcdVersionCheck) getHTTPClient(config *tls.Config) *http.Clie
}
return &http.Client{Timeout: externalEtcdRequestTimeout}
}
func getEtcdVersionResponse(client *http.Client, url string, target interface{}) error {
loopCount := externalEtcdRequestRetries + 1
var err error
@ -590,6 +612,8 @@ func getEtcdVersionResponse(client *http.Client, url string, target interface{})
}
return err
}
// RunInitMasterChecks executes all individual, applicable to Master node checks.
func RunInitMasterChecks(cfg *kubeadmapi.MasterConfiguration) error {
// First, check if we're root separately from the other preflight checks and fail fast
if err := RunRootCheckOnly(); err != nil {
@ -655,6 +679,7 @@ func RunInitMasterChecks(cfg *kubeadmapi.MasterConfiguration) error {
return RunChecks(checks, os.Stderr)
}
// RunJoinNodeChecks executes all individual, applicable to node checks.
func RunJoinNodeChecks(cfg *kubeadmapi.NodeConfiguration) error {
// First, check if we're root separately from the other preflight checks and fail fast
if err := RunRootCheckOnly(); err != nil {
@ -688,6 +713,7 @@ func RunJoinNodeChecks(cfg *kubeadmapi.NodeConfiguration) error {
return RunChecks(checks, os.Stderr)
}
// RunRootCheckOnly initializes cheks slice of structs and call RunChecks
func RunRootCheckOnly() error {
checks := []Checker{
IsRootCheck{},
@ -717,6 +743,7 @@ func RunChecks(checks []Checker, ww io.Writer) error {
return nil
}
// TryStartKubelet attempts to bring up kubelet service
func TryStartKubelet() {
// If we notice that the kubelet service is inactive, try to start it
initSystem, err := initsystem.GetInitSystem()

View File

@ -34,6 +34,7 @@ import (
"k8s.io/kubernetes/pkg/util/version"
)
// SetInitDynamicDefaults checks and sets conifugration values for Master node
func SetInitDynamicDefaults(cfg *kubeadmapi.MasterConfiguration) error {
// Choose the right address for the API Server to advertise. If the advertise address is localhost or 0.0.0.0, the default interface's IP address is used
@ -48,7 +49,6 @@ func SetInitDynamicDefaults(cfg *kubeadmapi.MasterConfiguration) error {
if kubeadmutil.KubernetesIsCIVersion(cfg.KubernetesVersion) {
cfg.CIImageRepository = kubeadmconstants.DefaultCIImageRepository
}
// Validate version argument
ver, err := kubeadmutil.KubernetesReleaseVersion(cfg.KubernetesVersion)
if err != nil {
@ -112,7 +112,6 @@ func ConfigFileAndDefaultsToInternalConfig(cfgPath string, defaultversionedcfg *
// static default values to cfg only for values not provided with flags
api.Scheme.Default(defaultversionedcfg)
api.Scheme.Convert(defaultversionedcfg, internalcfg, nil)
// Applies dynamic defaults to settings not provided with flags
if err := SetInitDynamicDefaults(internalcfg); err != nil {
return nil, err

View File

@ -26,9 +26,12 @@ import (
)
const (
// DefaultErrorExitCode defines exit the code for failed action generally
DefaultErrorExitCode = 1
PreFlightExitCode = 2
ValidationExitCode = 3
// PreFlightExitCode defines exit the code for preflight checks
PreFlightExitCode = 2
// ValidationExitCode defines the exit code validation checks
ValidationExitCode = 3
)
type debugError interface {

View File

@ -72,11 +72,11 @@ func ClientSetFromFile(path string) (*clientset.Clientset, error) {
if err != nil {
return nil, fmt.Errorf("failed to load admin kubeconfig [%v]", err)
}
return KubeConfigToClientSet(config)
return ToClientSet(config)
}
// KubeConfigToClientSet converts a KubeConfig object to a client
func KubeConfigToClientSet(config *clientcmdapi.Config) (*clientset.Clientset, error) {
// ToClientSet converts a KubeConfig object to a client
func ToClientSet(config *clientcmdapi.Config) (*clientset.Clientset, error) {
clientConfig, err := clientcmd.NewDefaultClientConfig(*config, &clientcmd.ConfigOverrides{}).ClientConfig()
if err != nil {
return nil, fmt.Errorf("failed to create API client configuration from kubeconfig: %v", err)

View File

@ -22,6 +22,7 @@ import (
"text/template"
)
// ParseTemplate validates and parses passed as argument template
func ParseTemplate(strtmpl string, obj interface{}) ([]byte, error) {
var buf bytes.Buffer
tmpl, err := template.New("template").Parse(strtmpl)

View File

@ -26,15 +26,21 @@ import (
)
const (
TokenIDBytes = 3
// TokenIDBytes defines a number of bytes used for a token id
TokenIDBytes = 3
// TokenSecretBytes defines a number of bytes used for a secret
TokenSecretBytes = 8
)
var (
// TokenIDRegexpString defines token's id regular expression pattern
TokenIDRegexpString = "^([a-z0-9]{6})$"
TokenIDRegexp = regexp.MustCompile(TokenIDRegexpString)
TokenRegexpString = "^([a-z0-9]{6})\\.([a-z0-9]{16})$"
TokenRegexp = regexp.MustCompile(TokenRegexpString)
// TokenIDRegexp is a compiled regular expression of TokenIDRegexpString
TokenIDRegexp = regexp.MustCompile(TokenIDRegexpString)
// TokenRegexpString defines id.secret regular expression pattern
TokenRegexpString = "^([a-z0-9]{6})\\.([a-z0-9]{16})$"
// TokenRegexp is a compiled regular expression of TokenRegexpString
TokenRegexp = regexp.MustCompile(TokenRegexpString)
)
func randBytes(length int) (string, error) {

View File

@ -187,7 +187,6 @@ func TestSplitVersion(t *testing.T) {
// unknown area, not valid input.
{"unknown/latest-1", "", "", false},
}
// kubeReleaseBucketURL can be overriden during network tests, thus ensure
// it will contain value corresponding to expected outcome for this unit test
kubeReleaseBucketURL = "https://dl.k8s.io"

View File

@ -27,6 +27,8 @@ import (
// Forked from test/e2e/framework because the e2e framework is quite bloated
// for our purposes here, and modified to remove undesired logging.
// RunCmd is a utility function for kubeadm testing that executes a specified command
func RunCmd(command string, args ...string) (string, string, error) {
var bout, berr bytes.Buffer
cmd := exec.Command(command, args...)

View File

@ -9,21 +9,6 @@ cmd/kube-proxy/app
cmd/kubeadm/app
cmd/kubeadm/app/apis/kubeadm
cmd/kubeadm/app/apis/kubeadm/v1alpha1
cmd/kubeadm/app/apis/kubeadm/validation
cmd/kubeadm/app/cmd
cmd/kubeadm/app/cmd/phases
cmd/kubeadm/app/constants
cmd/kubeadm/app/discovery
cmd/kubeadm/app/discovery/file
cmd/kubeadm/app/discovery/token
cmd/kubeadm/app/images
cmd/kubeadm/app/phases/certs/pkiutil
cmd/kubeadm/app/preflight
cmd/kubeadm/app/util
cmd/kubeadm/app/util/config
cmd/kubeadm/app/util/kubeconfig
cmd/kubeadm/app/util/token
cmd/kubeadm/test/cmd
cmd/kubectl/app
cmd/kubelet/app
cmd/kubelet/app/options