[kubeadm/app/]switch to github.com/pkg/errors
Signed-off-by: yuexiao-wang <wang.yuexiao@zte.com.cn>
This commit is contained in:
@@ -17,11 +17,12 @@ limitations under the License.
|
|||||||
package kubeadm
|
package kubeadm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
bootstrapapi "k8s.io/cluster-bootstrap/token/api"
|
bootstrapapi "k8s.io/cluster-bootstrap/token/api"
|
||||||
@@ -84,24 +85,24 @@ func BootstrapTokenFromSecret(secret *v1.Secret) (*BootstrapToken, error) {
|
|||||||
// Get the Token ID field from the Secret data
|
// Get the Token ID field from the Secret data
|
||||||
tokenID := getSecretString(secret, bootstrapapi.BootstrapTokenIDKey)
|
tokenID := getSecretString(secret, bootstrapapi.BootstrapTokenIDKey)
|
||||||
if len(tokenID) == 0 {
|
if len(tokenID) == 0 {
|
||||||
return nil, fmt.Errorf("Bootstrap Token Secret has no token-id data: %s", secret.Name)
|
return nil, errors.Errorf("bootstrap Token Secret has no token-id data: %s", secret.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enforce the right naming convention
|
// Enforce the right naming convention
|
||||||
if secret.Name != bootstraputil.BootstrapTokenSecretName(tokenID) {
|
if secret.Name != bootstraputil.BootstrapTokenSecretName(tokenID) {
|
||||||
return nil, fmt.Errorf("bootstrap token name is not of the form '%s(token-id)'. Actual: %q. Expected: %q",
|
return nil, errors.Errorf("bootstrap token name is not of the form '%s(token-id)'. Actual: %q. Expected: %q",
|
||||||
bootstrapapi.BootstrapTokenSecretPrefix, secret.Name, bootstraputil.BootstrapTokenSecretName(tokenID))
|
bootstrapapi.BootstrapTokenSecretPrefix, secret.Name, bootstraputil.BootstrapTokenSecretName(tokenID))
|
||||||
}
|
}
|
||||||
|
|
||||||
tokenSecret := getSecretString(secret, bootstrapapi.BootstrapTokenSecretKey)
|
tokenSecret := getSecretString(secret, bootstrapapi.BootstrapTokenSecretKey)
|
||||||
if len(tokenSecret) == 0 {
|
if len(tokenSecret) == 0 {
|
||||||
return nil, fmt.Errorf("Bootstrap Token Secret has no token-secret data: %s", secret.Name)
|
return nil, errors.Errorf("bootstrap Token Secret has no token-secret data: %s", secret.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the BootstrapTokenString object based on the ID and Secret
|
// Create the BootstrapTokenString object based on the ID and Secret
|
||||||
bts, err := NewBootstrapTokenStringFromIDAndSecret(tokenID, tokenSecret)
|
bts, err := NewBootstrapTokenStringFromIDAndSecret(tokenID, tokenSecret)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Bootstrap Token Secret is invalid and couldn't be parsed: %v", err)
|
return nil, errors.Wrap(err, "bootstrap Token Secret is invalid and couldn't be parsed")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the description (if any) from the Secret
|
// Get the description (if any) from the Secret
|
||||||
@@ -114,7 +115,7 @@ func BootstrapTokenFromSecret(secret *v1.Secret) (*BootstrapToken, error) {
|
|||||||
if len(secretExpiration) > 0 {
|
if len(secretExpiration) > 0 {
|
||||||
expTime, err := time.Parse(time.RFC3339, secretExpiration)
|
expTime, err := time.Parse(time.RFC3339, secretExpiration)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("can't parse expiration time of bootstrap token %q: %v", secret.Name, err)
|
return nil, errors.Wrapf(err, "can't parse expiration time of bootstrap token %q", secret.Name)
|
||||||
}
|
}
|
||||||
expires = &metav1.Time{Time: expTime}
|
expires = &metav1.Time{Time: expTime}
|
||||||
}
|
}
|
||||||
|
@@ -24,6 +24,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
bootstrapapi "k8s.io/cluster-bootstrap/token/api"
|
bootstrapapi "k8s.io/cluster-bootstrap/token/api"
|
||||||
bootstraputil "k8s.io/cluster-bootstrap/token/util"
|
bootstraputil "k8s.io/cluster-bootstrap/token/util"
|
||||||
)
|
)
|
||||||
@@ -77,7 +79,7 @@ func NewBootstrapTokenString(token string) (*BootstrapTokenString, error) {
|
|||||||
substrs := bootstraputil.BootstrapTokenRegexp.FindStringSubmatch(token)
|
substrs := bootstraputil.BootstrapTokenRegexp.FindStringSubmatch(token)
|
||||||
// TODO: Add a constant for the 3 value here, and explain better why it's needed (other than because how the regexp parsin works)
|
// TODO: Add a constant for the 3 value here, and explain better why it's needed (other than because how the regexp parsin works)
|
||||||
if len(substrs) != 3 {
|
if len(substrs) != 3 {
|
||||||
return nil, fmt.Errorf("the bootstrap token %q was not of the form %q", token, bootstrapapi.BootstrapTokenPattern)
|
return nil, errors.Errorf("the bootstrap token %q was not of the form %q", token, bootstrapapi.BootstrapTokenPattern)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &BootstrapTokenString{ID: substrs[1], Secret: substrs[2]}, nil
|
return &BootstrapTokenString{ID: substrs[1], Secret: substrs[2]}, nil
|
||||||
|
@@ -18,9 +18,10 @@ package kubeadm
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMarshalJSON(t *testing.T) {
|
func TestMarshalJSON(t *testing.T) {
|
||||||
@@ -99,13 +100,13 @@ func roundtrip(input string, bts *BootstrapTokenString) error {
|
|||||||
// If string input was specified, roundtrip like this: string -> (unmarshal) -> object -> (marshal) -> string
|
// If string input was specified, roundtrip like this: string -> (unmarshal) -> object -> (marshal) -> string
|
||||||
if len(input) > 0 {
|
if len(input) > 0 {
|
||||||
if err := json.Unmarshal([]byte(input), newbts); err != nil {
|
if err := json.Unmarshal([]byte(input), newbts); err != nil {
|
||||||
return fmt.Errorf("expected no unmarshal error, got error: %v", err)
|
return errors.Wrap(err, "expected no unmarshal error, got error")
|
||||||
}
|
}
|
||||||
if b, err = json.Marshal(newbts); err != nil {
|
if b, err = json.Marshal(newbts); err != nil {
|
||||||
return fmt.Errorf("expected no marshal error, got error: %v", err)
|
return errors.Wrap(err, "expected no marshal error, got error")
|
||||||
}
|
}
|
||||||
if input != string(b) {
|
if input != string(b) {
|
||||||
return fmt.Errorf(
|
return errors.Errorf(
|
||||||
"expected token: %s\n\t actual: %s",
|
"expected token: %s\n\t actual: %s",
|
||||||
input,
|
input,
|
||||||
string(b),
|
string(b),
|
||||||
@@ -113,13 +114,13 @@ func roundtrip(input string, bts *BootstrapTokenString) error {
|
|||||||
}
|
}
|
||||||
} else { // Otherwise, roundtrip like this: object -> (marshal) -> string -> (unmarshal) -> object
|
} else { // Otherwise, roundtrip like this: object -> (marshal) -> string -> (unmarshal) -> object
|
||||||
if b, err = json.Marshal(bts); err != nil {
|
if b, err = json.Marshal(bts); err != nil {
|
||||||
return fmt.Errorf("expected no marshal error, got error: %v", err)
|
return errors.Wrap(err, "expected no marshal error, got error")
|
||||||
}
|
}
|
||||||
if err := json.Unmarshal(b, newbts); err != nil {
|
if err := json.Unmarshal(b, newbts); err != nil {
|
||||||
return fmt.Errorf("expected no unmarshal error, got error: %v", err)
|
return errors.Wrap(err, "expected no unmarshal error, got error")
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(bts, newbts) {
|
if !reflect.DeepEqual(bts, newbts) {
|
||||||
return fmt.Errorf(
|
return errors.Errorf(
|
||||||
"expected object: %v\n\t actual: %v",
|
"expected object: %v\n\t actual: %v",
|
||||||
bts,
|
bts,
|
||||||
newbts,
|
newbts,
|
||||||
|
@@ -20,6 +20,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
bootstrapapi "k8s.io/cluster-bootstrap/token/api"
|
bootstrapapi "k8s.io/cluster-bootstrap/token/api"
|
||||||
bootstraputil "k8s.io/cluster-bootstrap/token/util"
|
bootstraputil "k8s.io/cluster-bootstrap/token/util"
|
||||||
)
|
)
|
||||||
@@ -73,7 +75,7 @@ func NewBootstrapTokenString(token string) (*BootstrapTokenString, error) {
|
|||||||
substrs := bootstraputil.BootstrapTokenRegexp.FindStringSubmatch(token)
|
substrs := bootstraputil.BootstrapTokenRegexp.FindStringSubmatch(token)
|
||||||
// TODO: Add a constant for the 3 value here, and explain better why it's needed (other than because how the regexp parsin works)
|
// TODO: Add a constant for the 3 value here, and explain better why it's needed (other than because how the regexp parsin works)
|
||||||
if len(substrs) != 3 {
|
if len(substrs) != 3 {
|
||||||
return nil, fmt.Errorf("the bootstrap token %q was not of the form %q", token, bootstrapapi.BootstrapTokenPattern)
|
return nil, errors.Errorf("the bootstrap token %q was not of the form %q", token, bootstrapapi.BootstrapTokenPattern)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &BootstrapTokenString{ID: substrs[1], Secret: substrs[2]}, nil
|
return &BootstrapTokenString{ID: substrs[1], Secret: substrs[2]}, nil
|
||||||
|
@@ -18,9 +18,10 @@ package v1alpha3
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMarshalJSON(t *testing.T) {
|
func TestMarshalJSON(t *testing.T) {
|
||||||
@@ -99,13 +100,13 @@ func roundtrip(input string, bts *BootstrapTokenString) error {
|
|||||||
// If string input was specified, roundtrip like this: string -> (unmarshal) -> object -> (marshal) -> string
|
// If string input was specified, roundtrip like this: string -> (unmarshal) -> object -> (marshal) -> string
|
||||||
if len(input) > 0 {
|
if len(input) > 0 {
|
||||||
if err := json.Unmarshal([]byte(input), newbts); err != nil {
|
if err := json.Unmarshal([]byte(input), newbts); err != nil {
|
||||||
return fmt.Errorf("expected no unmarshal error, got error: %v", err)
|
return errors.Wrap(err, "expected no unmarshal error, got error")
|
||||||
}
|
}
|
||||||
if b, err = json.Marshal(newbts); err != nil {
|
if b, err = json.Marshal(newbts); err != nil {
|
||||||
return fmt.Errorf("expected no marshal error, got error: %v", err)
|
return errors.Wrap(err, "expected no marshal error, got error")
|
||||||
}
|
}
|
||||||
if input != string(b) {
|
if input != string(b) {
|
||||||
return fmt.Errorf(
|
return errors.Errorf(
|
||||||
"expected token: %s\n\t actual: %s",
|
"expected token: %s\n\t actual: %s",
|
||||||
input,
|
input,
|
||||||
string(b),
|
string(b),
|
||||||
@@ -113,13 +114,13 @@ func roundtrip(input string, bts *BootstrapTokenString) error {
|
|||||||
}
|
}
|
||||||
} else { // Otherwise, roundtrip like this: object -> (marshal) -> string -> (unmarshal) -> object
|
} else { // Otherwise, roundtrip like this: object -> (marshal) -> string -> (unmarshal) -> object
|
||||||
if b, err = json.Marshal(bts); err != nil {
|
if b, err = json.Marshal(bts); err != nil {
|
||||||
return fmt.Errorf("expected no marshal error, got error: %v", err)
|
return errors.Wrap(err, "expected no marshal error, got error")
|
||||||
}
|
}
|
||||||
if err := json.Unmarshal(b, newbts); err != nil {
|
if err := json.Unmarshal(b, newbts); err != nil {
|
||||||
return fmt.Errorf("expected no unmarshal error, got error: %v", err)
|
return errors.Wrap(err, "expected no unmarshal error, got error")
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(bts, newbts) {
|
if !reflect.DeepEqual(bts, newbts) {
|
||||||
return fmt.Errorf(
|
return errors.Errorf(
|
||||||
"expected object: %v\n\t actual: %v",
|
"expected object: %v\n\t actual: %v",
|
||||||
bts,
|
bts,
|
||||||
newbts,
|
newbts,
|
||||||
|
@@ -20,6 +20,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
bootstrapapi "k8s.io/cluster-bootstrap/token/api"
|
bootstrapapi "k8s.io/cluster-bootstrap/token/api"
|
||||||
bootstraputil "k8s.io/cluster-bootstrap/token/util"
|
bootstraputil "k8s.io/cluster-bootstrap/token/util"
|
||||||
)
|
)
|
||||||
@@ -73,7 +75,7 @@ func NewBootstrapTokenString(token string) (*BootstrapTokenString, error) {
|
|||||||
substrs := bootstraputil.BootstrapTokenRegexp.FindStringSubmatch(token)
|
substrs := bootstraputil.BootstrapTokenRegexp.FindStringSubmatch(token)
|
||||||
// TODO: Add a constant for the 3 value here, and explain better why it's needed (other than because how the regexp parsin works)
|
// TODO: Add a constant for the 3 value here, and explain better why it's needed (other than because how the regexp parsin works)
|
||||||
if len(substrs) != 3 {
|
if len(substrs) != 3 {
|
||||||
return nil, fmt.Errorf("the bootstrap token %q was not of the form %q", token, bootstrapapi.BootstrapTokenPattern)
|
return nil, errors.Errorf("the bootstrap token %q was not of the form %q", token, bootstrapapi.BootstrapTokenPattern)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &BootstrapTokenString{ID: substrs[1], Secret: substrs[2]}, nil
|
return &BootstrapTokenString{ID: substrs[1], Secret: substrs[2]}, nil
|
||||||
|
@@ -18,9 +18,10 @@ package v1beta1
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMarshalJSON(t *testing.T) {
|
func TestMarshalJSON(t *testing.T) {
|
||||||
@@ -99,13 +100,13 @@ func roundtrip(input string, bts *BootstrapTokenString) error {
|
|||||||
// If string input was specified, roundtrip like this: string -> (unmarshal) -> object -> (marshal) -> string
|
// If string input was specified, roundtrip like this: string -> (unmarshal) -> object -> (marshal) -> string
|
||||||
if len(input) > 0 {
|
if len(input) > 0 {
|
||||||
if err := json.Unmarshal([]byte(input), newbts); err != nil {
|
if err := json.Unmarshal([]byte(input), newbts); err != nil {
|
||||||
return fmt.Errorf("expected no unmarshal error, got error: %v", err)
|
return errors.Wrap(err, "expected no unmarshal error, got error")
|
||||||
}
|
}
|
||||||
if b, err = json.Marshal(newbts); err != nil {
|
if b, err = json.Marshal(newbts); err != nil {
|
||||||
return fmt.Errorf("expected no marshal error, got error: %v", err)
|
return errors.Wrap(err, "expected no marshal error, got error")
|
||||||
}
|
}
|
||||||
if input != string(b) {
|
if input != string(b) {
|
||||||
return fmt.Errorf(
|
return errors.Errorf(
|
||||||
"expected token: %s\n\t actual: %s",
|
"expected token: %s\n\t actual: %s",
|
||||||
input,
|
input,
|
||||||
string(b),
|
string(b),
|
||||||
@@ -113,13 +114,13 @@ func roundtrip(input string, bts *BootstrapTokenString) error {
|
|||||||
}
|
}
|
||||||
} else { // Otherwise, roundtrip like this: object -> (marshal) -> string -> (unmarshal) -> object
|
} else { // Otherwise, roundtrip like this: object -> (marshal) -> string -> (unmarshal) -> object
|
||||||
if b, err = json.Marshal(bts); err != nil {
|
if b, err = json.Marshal(bts); err != nil {
|
||||||
return fmt.Errorf("expected no marshal error, got error: %v", err)
|
return errors.Wrap(err, "expected no marshal error, got error")
|
||||||
}
|
}
|
||||||
if err := json.Unmarshal(b, newbts); err != nil {
|
if err := json.Unmarshal(b, newbts); err != nil {
|
||||||
return fmt.Errorf("expected no unmarshal error, got error: %v", err)
|
return errors.Wrap(err, "expected no unmarshal error, got error")
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(bts, newbts) {
|
if !reflect.DeepEqual(bts, newbts) {
|
||||||
return fmt.Errorf(
|
return errors.Errorf(
|
||||||
"expected object: %v\n\t actual: %v",
|
"expected object: %v\n\t actual: %v",
|
||||||
bts,
|
bts,
|
||||||
newbts,
|
newbts,
|
||||||
|
@@ -25,6 +25,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
@@ -398,7 +399,7 @@ func ValidateMixedArguments(flag *pflag.FlagSet) error {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if len(mixedInvalidFlags) != 0 {
|
if len(mixedInvalidFlags) != 0 {
|
||||||
return fmt.Errorf("can not mix '--config' with arguments %v", mixedInvalidFlags)
|
return errors.Errorf("can not mix '--config' with arguments %v", mixedInvalidFlags)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@@ -18,7 +18,6 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
@@ -126,7 +125,7 @@ func RunCompletion(out io.Writer, boilerPlate string, cmd *cobra.Command, args [
|
|||||||
}
|
}
|
||||||
run, found := completionShells[args[0]]
|
run, found := completionShells[args[0]]
|
||||||
if !found {
|
if !found {
|
||||||
return fmt.Errorf("unsupported shell type %q", args[0])
|
return errors.Errorf("unsupported shell type %q", args[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(boilerPlate) == 0 {
|
if len(boilerPlate) == 0 {
|
||||||
|
@@ -188,7 +188,7 @@ func NewCmdConfigPrintDefault(out io.Writer) *cobra.Command {
|
|||||||
func getDefaultComponentConfigAPIObjectBytes(apiObject string) ([]byte, error) {
|
func getDefaultComponentConfigAPIObjectBytes(apiObject string) ([]byte, error) {
|
||||||
registration, ok := componentconfigs.Known[componentconfigs.RegistrationKind(apiObject)]
|
registration, ok := componentconfigs.Known[componentconfigs.RegistrationKind(apiObject)]
|
||||||
if !ok {
|
if !ok {
|
||||||
return []byte{}, fmt.Errorf("--component-configs needs to contain some of %v", getSupportedComponentConfigAPIObjects())
|
return []byte{}, errors.Errorf("--component-configs needs to contain some of %v", getSupportedComponentConfigAPIObjects())
|
||||||
}
|
}
|
||||||
return getDefaultComponentConfigBytes(registration)
|
return getDefaultComponentConfigBytes(registration)
|
||||||
}
|
}
|
||||||
@@ -208,7 +208,7 @@ func getDefaultAPIObjectBytes(apiObject string) ([]byte, error) {
|
|||||||
// Is this a component config?
|
// Is this a component config?
|
||||||
registration, ok := componentconfigs.Known[componentconfigs.RegistrationKind(apiObject)]
|
registration, ok := componentconfigs.Known[componentconfigs.RegistrationKind(apiObject)]
|
||||||
if !ok {
|
if !ok {
|
||||||
return []byte{}, fmt.Errorf("--api-object needs to be one of %v", getAllAPIObjectNames())
|
return []byte{}, errors.Errorf("--api-object needs to be one of %v", getAllAPIObjectNames())
|
||||||
}
|
}
|
||||||
return getDefaultComponentConfigBytes(registration)
|
return getDefaultComponentConfigBytes(registration)
|
||||||
}
|
}
|
||||||
@@ -339,7 +339,7 @@ func NewCmdConfigMigrate(out io.Writer) *cobra.Command {
|
|||||||
fmt.Fprint(out, string(outputBytes))
|
fmt.Fprint(out, string(outputBytes))
|
||||||
} else {
|
} else {
|
||||||
if err := ioutil.WriteFile(newCfgPath, outputBytes, 0644); err != nil {
|
if err := ioutil.WriteFile(newCfgPath, outputBytes, 0644); err != nil {
|
||||||
kubeadmutil.CheckErr(fmt.Errorf("failed to write the new configuration to the file %q: %v", newCfgPath, err))
|
kubeadmutil.CheckErr(errors.Wrapf(err, "failed to write the new configuration to the file %q", newCfgPath))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -545,7 +545,7 @@ func NewImagesPull(runtime utilruntime.ContainerRuntime, images []string) *Image
|
|||||||
func (ip *ImagesPull) PullAll() error {
|
func (ip *ImagesPull) PullAll() error {
|
||||||
for _, image := range ip.images {
|
for _, image := range ip.images {
|
||||||
if err := ip.runtime.PullImage(image); err != nil {
|
if err := ip.runtime.PullImage(image); err != nil {
|
||||||
return fmt.Errorf("failed to pull image %q: %v", image, err)
|
return errors.Wrapf(err, "failed to pull image %q", image)
|
||||||
}
|
}
|
||||||
fmt.Printf("[config/images] Pulled %s\n", image)
|
fmt.Printf("[config/images] Pulled %s\n", image)
|
||||||
}
|
}
|
||||||
|
@@ -448,12 +448,12 @@ func runInit(i *initData, out io.Writer) error {
|
|||||||
if i.cfg.AuditPolicyConfiguration.Path != "" {
|
if i.cfg.AuditPolicyConfiguration.Path != "" {
|
||||||
// TODO(chuckha) ensure passed in audit policy is valid so users don't have to find the error in the api server log.
|
// TODO(chuckha) ensure passed in audit policy is valid so users don't have to find the error in the api server log.
|
||||||
if _, err := os.Stat(i.cfg.AuditPolicyConfiguration.Path); err != nil {
|
if _, err := os.Stat(i.cfg.AuditPolicyConfiguration.Path); err != nil {
|
||||||
return fmt.Errorf("error getting file info for audit policy file %q [%v]", i.cfg.AuditPolicyConfiguration.Path, err)
|
return errors.Wrapf(err, "error getting file info for audit policy file %q", i.cfg.AuditPolicyConfiguration.Path)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
i.cfg.AuditPolicyConfiguration.Path = filepath.Join(kubeConfigDir, kubeadmconstants.AuditPolicyDir, kubeadmconstants.AuditPolicyFile)
|
i.cfg.AuditPolicyConfiguration.Path = filepath.Join(kubeConfigDir, kubeadmconstants.AuditPolicyDir, kubeadmconstants.AuditPolicyFile)
|
||||||
if err := auditutil.CreateDefaultAuditLogPolicy(i.cfg.AuditPolicyConfiguration.Path); err != nil {
|
if err := auditutil.CreateDefaultAuditLogPolicy(i.cfg.AuditPolicyConfiguration.Path); err != nil {
|
||||||
return fmt.Errorf("error creating default audit policy %q [%v]", i.cfg.AuditPolicyConfiguration.Path, err)
|
return errors.Wrapf(err, "error creating default audit policy %q ", i.cfg.AuditPolicyConfiguration.Path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -570,7 +570,7 @@ func runInit(i *initData, out io.Writer) error {
|
|||||||
// Create RBAC rules that makes the bootstrap tokens able to get their CSRs approved automatically
|
// Create RBAC rules that makes the bootstrap tokens able to get their CSRs approved automatically
|
||||||
glog.V(1).Infof("[init] creating RBAC rules to automatic approval of CSRs automatically")
|
glog.V(1).Infof("[init] creating RBAC rules to automatic approval of CSRs automatically")
|
||||||
if err := nodebootstraptokenphase.AutoApproveNodeBootstrapTokens(client); err != nil {
|
if err := nodebootstraptokenphase.AutoApproveNodeBootstrapTokens(client); err != nil {
|
||||||
return errors.Wrap(err, "error auto-approving node bootstrap tokens: %v")
|
return errors.Wrap(err, "error auto-approving node bootstrap tokens")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create/update RBAC rules that makes the nodes to rotate certificates and get their CSRs approved automatically
|
// Create/update RBAC rules that makes the nodes to rotate certificates and get their CSRs approved automatically
|
||||||
|
@@ -514,7 +514,7 @@ func (j *Join) BootstrapKubelet(tlsBootstrapCfg *clientcmdapi.Config) error {
|
|||||||
|
|
||||||
bootstrapClient, err := kubeconfigutil.ClientSetFromFile(bootstrapKubeConfigFile)
|
bootstrapClient, err := kubeconfigutil.ClientSetFromFile(bootstrapKubeConfigFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("couldn't create client from kubeconfig file %q", bootstrapKubeConfigFile)
|
return errors.Errorf("couldn't create client from kubeconfig file %q", bootstrapKubeConfigFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure the kubelet. In this short timeframe, kubeadm is trying to stop/restart the kubelet
|
// Configure the kubelet. In this short timeframe, kubeadm is trying to stop/restart the kubelet
|
||||||
@@ -597,7 +597,7 @@ func (j *Join) PostInstallControlPlane(initConfiguration *kubeadmapi.InitConfigu
|
|||||||
|
|
||||||
glog.V(1).Info("[join] uploading currently used configuration to the cluster")
|
glog.V(1).Info("[join] uploading currently used configuration to the cluster")
|
||||||
if err := uploadconfigphase.UploadConfiguration(initConfiguration, client); err != nil {
|
if err := uploadconfigphase.UploadConfiguration(initConfiguration, client); err != nil {
|
||||||
return errors.Wrap(err, "error uploading configuration: %v")
|
return errors.Wrap(err, "error uploading configuration")
|
||||||
}
|
}
|
||||||
|
|
||||||
glog.V(1).Info("[join] marking the master with right label")
|
glog.V(1).Info("[join] marking the master with right label")
|
||||||
|
@@ -78,7 +78,7 @@ func NewPreflightMasterPhase() workflow.Phase {
|
|||||||
func runPreflightMaster(c workflow.RunData) error {
|
func runPreflightMaster(c workflow.RunData) error {
|
||||||
data, ok := c.(preflightMasterData)
|
data, ok := c.(preflightMasterData)
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("preflight phase invoked with an invalid data struct")
|
return errors.New("preflight phase invoked with an invalid data struct")
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("[preflight] running pre-flight checks")
|
fmt.Println("[preflight] running pre-flight checks")
|
||||||
|
@@ -21,6 +21,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
)
|
)
|
||||||
@@ -135,7 +136,7 @@ func (e *Runner) computePhaseRunFlags() (map[string]bool, error) {
|
|||||||
}
|
}
|
||||||
for _, f := range e.Options.FilterPhases {
|
for _, f := range e.Options.FilterPhases {
|
||||||
if _, ok := phaseRunFlags[f]; !ok {
|
if _, ok := phaseRunFlags[f]; !ok {
|
||||||
return phaseRunFlags, fmt.Errorf("invalid phase name: %s", f)
|
return phaseRunFlags, errors.Errorf("invalid phase name: %s", f)
|
||||||
}
|
}
|
||||||
phaseRunFlags[f] = true
|
phaseRunFlags[f] = true
|
||||||
for _, c := range phaseHierarchy[f] {
|
for _, c := range phaseHierarchy[f] {
|
||||||
@@ -148,7 +149,7 @@ func (e *Runner) computePhaseRunFlags() (map[string]bool, error) {
|
|||||||
// to false and apply the same change to the underlying hierarchy
|
// to false and apply the same change to the underlying hierarchy
|
||||||
for _, f := range e.Options.SkipPhases {
|
for _, f := range e.Options.SkipPhases {
|
||||||
if _, ok := phaseRunFlags[f]; !ok {
|
if _, ok := phaseRunFlags[f]; !ok {
|
||||||
return phaseRunFlags, fmt.Errorf("invalid phase name: %s", f)
|
return phaseRunFlags, errors.Errorf("invalid phase name: %s", f)
|
||||||
}
|
}
|
||||||
phaseRunFlags[f] = false
|
phaseRunFlags[f] = false
|
||||||
for _, c := range phaseHierarchy[f] {
|
for _, c := range phaseHierarchy[f] {
|
||||||
@@ -206,7 +207,7 @@ func (e *Runner) Run() error {
|
|||||||
// Check the condition and returns if the condition isn't satisfied (or fails)
|
// Check the condition and returns if the condition isn't satisfied (or fails)
|
||||||
ok, err := p.RunIf(data)
|
ok, err := p.RunIf(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error execution run condition for phase %s: %v", p.generatedName, err)
|
return errors.Wrapf(err, "error execution run condition for phase %s", p.generatedName)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -217,7 +218,7 @@ func (e *Runner) Run() error {
|
|||||||
// Runs the phase action (if defined)
|
// Runs the phase action (if defined)
|
||||||
if p.Run != nil {
|
if p.Run != nil {
|
||||||
if err := p.Run(data); err != nil {
|
if err := p.Run(data); err != nil {
|
||||||
return fmt.Errorf("error execution phase %s: %v", p.generatedName, err)
|
return errors.Wrapf(err, "error execution phase %s", p.generatedName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -170,7 +170,7 @@ func NewCmdToken(out io.Writer, errW io.Writer) *cobra.Command {
|
|||||||
`),
|
`),
|
||||||
Run: func(tokenCmd *cobra.Command, args []string) {
|
Run: func(tokenCmd *cobra.Command, args []string) {
|
||||||
if len(args) < 1 {
|
if len(args) < 1 {
|
||||||
kubeadmutil.CheckErr(fmt.Errorf("missing subcommand; 'token delete' is missing token of form %q", bootstrapapi.BootstrapTokenIDPattern))
|
kubeadmutil.CheckErr(errors.Errorf("missing subcommand; 'token delete' is missing token of form %q", bootstrapapi.BootstrapTokenIDPattern))
|
||||||
}
|
}
|
||||||
kubeConfigFile = cmdutil.FindExistingKubeConfig(kubeConfigFile)
|
kubeConfigFile = cmdutil.FindExistingKubeConfig(kubeConfigFile)
|
||||||
client, err := getClientset(kubeConfigFile, dryRun)
|
client, err := getClientset(kubeConfigFile, dryRun)
|
||||||
@@ -303,7 +303,8 @@ func RunDeleteToken(out io.Writer, client clientset.Interface, tokenIDOrToken st
|
|||||||
// Okay, the full token with both id and secret was probably passed. Parse it and extract the ID only
|
// Okay, the full token with both id and secret was probably passed. Parse it and extract the ID only
|
||||||
bts, err := kubeadmapiv1beta1.NewBootstrapTokenString(tokenIDOrToken)
|
bts, err := kubeadmapiv1beta1.NewBootstrapTokenString(tokenIDOrToken)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("given token or token id %q didn't match pattern %q or %q", tokenIDOrToken, bootstrapapi.BootstrapTokenIDPattern, bootstrapapi.BootstrapTokenIDPattern)
|
return errors.Errorf("given token or token id %q didn't match pattern %q or %q",
|
||||||
|
tokenIDOrToken, bootstrapapi.BootstrapTokenIDPattern, bootstrapapi.BootstrapTokenIDPattern)
|
||||||
}
|
}
|
||||||
tokenID = bts.ID
|
tokenID = bts.ID
|
||||||
}
|
}
|
||||||
|
@@ -22,6 +22,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"k8s.io/apimachinery/pkg/util/version"
|
"k8s.io/apimachinery/pkg/util/version"
|
||||||
clientset "k8s.io/client-go/kubernetes"
|
clientset "k8s.io/client-go/kubernetes"
|
||||||
@@ -168,7 +169,7 @@ func RunApply(flags *applyFlags) error {
|
|||||||
flags.newK8sVersionStr = upgradeVars.cfg.KubernetesVersion
|
flags.newK8sVersionStr = upgradeVars.cfg.KubernetesVersion
|
||||||
k8sVer, err := version.ParseSemantic(flags.newK8sVersionStr)
|
k8sVer, err := version.ParseSemantic(flags.newK8sVersionStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to parse normalized version %q as a semantic version", flags.newK8sVersionStr)
|
return errors.Errorf("unable to parse normalized version %q as a semantic version", flags.newK8sVersionStr)
|
||||||
}
|
}
|
||||||
flags.newK8sVersion = k8sVer
|
flags.newK8sVersion = k8sVer
|
||||||
|
|
||||||
@@ -179,7 +180,7 @@ func RunApply(flags *applyFlags) error {
|
|||||||
// Enforce the version skew policies
|
// Enforce the version skew policies
|
||||||
glog.V(1).Infof("[upgrade/version] enforcing version skew policies")
|
glog.V(1).Infof("[upgrade/version] enforcing version skew policies")
|
||||||
if err := EnforceVersionPolicies(flags, upgradeVars.versionGetter); err != nil {
|
if err := EnforceVersionPolicies(flags, upgradeVars.versionGetter); err != nil {
|
||||||
return fmt.Errorf("[upgrade/version] FATAL: %v", err)
|
return errors.Wrap(err, "[upgrade/version] FATAL")
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the current session is interactive, ask the user whether they really want to upgrade
|
// If the current session is interactive, ask the user whether they really want to upgrade
|
||||||
@@ -198,19 +199,19 @@ func RunApply(flags *applyFlags) error {
|
|||||||
componentsToPrepull = append(componentsToPrepull, constants.Etcd)
|
componentsToPrepull = append(componentsToPrepull, constants.Etcd)
|
||||||
}
|
}
|
||||||
if err := upgrade.PrepullImagesInParallel(prepuller, flags.imagePullTimeout, componentsToPrepull); err != nil {
|
if err := upgrade.PrepullImagesInParallel(prepuller, flags.imagePullTimeout, componentsToPrepull); err != nil {
|
||||||
return fmt.Errorf("[upgrade/prepull] Failed prepulled the images for the control plane components error: %v", err)
|
return errors.Wrap(err, "[upgrade/prepull] Failed prepulled the images for the control plane components error")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now; perform the upgrade procedure
|
// Now; perform the upgrade procedure
|
||||||
glog.V(1).Infof("[upgrade/apply] performing upgrade")
|
glog.V(1).Infof("[upgrade/apply] performing upgrade")
|
||||||
if err := PerformControlPlaneUpgrade(flags, upgradeVars.client, upgradeVars.waiter, upgradeVars.cfg); err != nil {
|
if err := PerformControlPlaneUpgrade(flags, upgradeVars.client, upgradeVars.waiter, upgradeVars.cfg); err != nil {
|
||||||
return fmt.Errorf("[upgrade/apply] FATAL: %v", err)
|
return errors.Wrap(err, "[upgrade/apply] FATAL")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Upgrade RBAC rules and addons.
|
// Upgrade RBAC rules and addons.
|
||||||
glog.V(1).Infof("[upgrade/postupgrade] upgrading RBAC rules and addons")
|
glog.V(1).Infof("[upgrade/postupgrade] upgrading RBAC rules and addons")
|
||||||
if err := upgrade.PerformPostUpgradeTasks(upgradeVars.client, upgradeVars.cfg, flags.newK8sVersion, flags.dryRun); err != nil {
|
if err := upgrade.PerformPostUpgradeTasks(upgradeVars.client, upgradeVars.cfg, flags.newK8sVersion, flags.dryRun); err != nil {
|
||||||
return fmt.Errorf("[upgrade/postupgrade] FATAL post-upgrade error: %v", err)
|
return errors.Wrap(err, "[upgrade/postupgrade] FATAL post-upgrade error")
|
||||||
}
|
}
|
||||||
|
|
||||||
if flags.dryRun {
|
if flags.dryRun {
|
||||||
@@ -234,7 +235,7 @@ func SetImplicitFlags(flags *applyFlags) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(flags.newK8sVersionStr) == 0 {
|
if len(flags.newK8sVersionStr) == 0 {
|
||||||
return fmt.Errorf("version string can't be empty")
|
return errors.New("version string can't be empty")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -249,13 +250,15 @@ func EnforceVersionPolicies(flags *applyFlags, versionGetter upgrade.VersionGett
|
|||||||
if versionSkewErrs != nil {
|
if versionSkewErrs != nil {
|
||||||
|
|
||||||
if len(versionSkewErrs.Mandatory) > 0 {
|
if len(versionSkewErrs.Mandatory) > 0 {
|
||||||
return fmt.Errorf("The --version argument is invalid due to these fatal errors:\n\n%v\nPlease fix the misalignments highlighted above and try upgrading again", kubeadmutil.FormatErrMsg(versionSkewErrs.Mandatory))
|
return errors.Errorf("the --version argument is invalid due to these fatal errors:\n\n%v\nPlease fix the misalignments highlighted above and try upgrading again",
|
||||||
|
kubeadmutil.FormatErrMsg(versionSkewErrs.Mandatory))
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(versionSkewErrs.Skippable) > 0 {
|
if len(versionSkewErrs.Skippable) > 0 {
|
||||||
// Return the error if the user hasn't specified the --force flag
|
// Return the error if the user hasn't specified the --force flag
|
||||||
if !flags.force {
|
if !flags.force {
|
||||||
return fmt.Errorf("The --version argument is invalid due to these errors:\n\n%v\nCan be bypassed if you pass the --force flag", kubeadmutil.FormatErrMsg(versionSkewErrs.Skippable))
|
return errors.Errorf("the --version argument is invalid due to these errors:\n\n%v\nCan be bypassed if you pass the --force flag",
|
||||||
|
kubeadmutil.FormatErrMsg(versionSkewErrs.Skippable))
|
||||||
}
|
}
|
||||||
// Soft errors found, but --force was specified
|
// 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: \n\n%v", len(versionSkewErrs.Skippable), kubeadmutil.FormatErrMsg(versionSkewErrs.Skippable))
|
fmt.Printf("[upgrade/version] Found %d potential version compatibility errors but skipping since the --force flag is set: \n\n%v", len(versionSkewErrs.Skippable), kubeadmutil.FormatErrMsg(versionSkewErrs.Skippable))
|
||||||
|
@@ -24,6 +24,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
@@ -54,12 +55,12 @@ func enforceRequirements(flags *applyPlanFlags, dryRun bool, newK8sVersion strin
|
|||||||
|
|
||||||
client, err := getClient(flags.kubeConfigPath, dryRun)
|
client, err := getClient(flags.kubeConfigPath, dryRun)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("couldn't create a Kubernetes client from file %q: %v", flags.kubeConfigPath, err)
|
return nil, errors.Wrapf(err, "couldn't create a Kubernetes client from file %q", flags.kubeConfigPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run healthchecks against the cluster
|
// Run healthchecks against the cluster
|
||||||
if err := upgrade.CheckClusterHealth(client, flags.ignorePreflightErrorsSet); err != nil {
|
if err := upgrade.CheckClusterHealth(client, flags.ignorePreflightErrorsSet); err != nil {
|
||||||
return nil, fmt.Errorf("[upgrade/health] FATAL: %v", err)
|
return nil, errors.Wrap(err, "[upgrade/health] FATAL")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch the configuration from a file or ConfigMap and validate it
|
// Fetch the configuration from a file or ConfigMap and validate it
|
||||||
@@ -75,9 +76,9 @@ func enforceRequirements(flags *applyPlanFlags, dryRun bool, newK8sVersion strin
|
|||||||
fmt.Printf("\t- OPTION 2: Run 'kubeadm config upload from-file' and specify the same config file you passed to 'kubeadm init' when you created your master.\n")
|
fmt.Printf("\t- OPTION 2: Run 'kubeadm config upload from-file' and specify the same config file you passed to 'kubeadm init' when you created your master.\n")
|
||||||
fmt.Printf("\t- OPTION 3: Pass a config file to 'kubeadm upgrade' using the --config flag.\n")
|
fmt.Printf("\t- OPTION 3: Pass a config file to 'kubeadm upgrade' using the --config flag.\n")
|
||||||
fmt.Println("")
|
fmt.Println("")
|
||||||
err = fmt.Errorf("the ConfigMap %q in the %s namespace used for getting configuration information was not found", constants.KubeadmConfigConfigMap, metav1.NamespaceSystem)
|
err = errors.Errorf("the ConfigMap %q in the %s namespace used for getting configuration information was not found", constants.KubeadmConfigConfigMap, metav1.NamespaceSystem)
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("[upgrade/config] FATAL: %v", err)
|
return nil, errors.Wrap(err, "[upgrade/config] FATAL")
|
||||||
}
|
}
|
||||||
|
|
||||||
// If a new k8s version should be set, apply the change before printing the config
|
// If a new k8s version should be set, apply the change before printing the config
|
||||||
@@ -89,7 +90,7 @@ func enforceRequirements(flags *applyPlanFlags, dryRun bool, newK8sVersion strin
|
|||||||
if flags.featureGatesString != "" {
|
if flags.featureGatesString != "" {
|
||||||
cfg.FeatureGates, err = features.NewFeatureGate(&features.InitFeatureGates, flags.featureGatesString)
|
cfg.FeatureGates, err = features.NewFeatureGate(&features.InitFeatureGates, flags.featureGatesString)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("[upgrade/config] FATAL: %v", err)
|
return nil, errors.Wrap(err, "[upgrade/config] FATAL")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,7 +99,7 @@ func enforceRequirements(flags *applyPlanFlags, dryRun bool, newK8sVersion strin
|
|||||||
for _, m := range msg {
|
for _, m := range msg {
|
||||||
fmt.Printf("[upgrade/config] %s\n", m)
|
fmt.Printf("[upgrade/config] %s\n", m)
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("[upgrade/config] FATAL. Unable to upgrade a cluster using deprecated feature-gate flags. Please see the release notes")
|
return nil, errors.New("[upgrade/config] FATAL. Unable to upgrade a cluster using deprecated feature-gate flags. Please see the release notes")
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the user told us to print this information out; do it!
|
// If the user told us to print this information out; do it!
|
||||||
@@ -153,7 +154,7 @@ func getClient(file string, dryRun bool) (clientset.Interface, error) {
|
|||||||
// API Server's version
|
// API Server's version
|
||||||
realServerVersion, err := dryRunGetter.Client().Discovery().ServerVersion()
|
realServerVersion, err := dryRunGetter.Client().Discovery().ServerVersion()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to get server version: %v", err)
|
return nil, errors.Wrap(err, "failed to get server version")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the fake clientset
|
// Get the fake clientset
|
||||||
@@ -165,7 +166,7 @@ func getClient(file string, dryRun bool) (clientset.Interface, error) {
|
|||||||
// we can convert it to that struct.
|
// we can convert it to that struct.
|
||||||
fakeclientDiscovery, ok := fakeclient.Discovery().(*fakediscovery.FakeDiscovery)
|
fakeclientDiscovery, ok := fakeclient.Discovery().(*fakediscovery.FakeDiscovery)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("couldn't set fake discovery's server version")
|
return nil, errors.New("couldn't set fake discovery's server version")
|
||||||
}
|
}
|
||||||
// Lastly, set the right server version to be used
|
// Lastly, set the right server version to be used
|
||||||
fakeclientDiscovery.FakedServerVersion = realServerVersion
|
fakeclientDiscovery.FakedServerVersion = realServerVersion
|
||||||
@@ -191,12 +192,12 @@ func InteractivelyConfirmUpgrade(question string) error {
|
|||||||
scanner := bufio.NewScanner(os.Stdin)
|
scanner := bufio.NewScanner(os.Stdin)
|
||||||
scanner.Scan()
|
scanner.Scan()
|
||||||
if err := scanner.Err(); err != nil {
|
if err := scanner.Err(); err != nil {
|
||||||
return fmt.Errorf("couldn't read from standard input: %v", err)
|
return errors.Wrap(err, "couldn't read from standard input")
|
||||||
}
|
}
|
||||||
answer := scanner.Text()
|
answer := scanner.Text()
|
||||||
if strings.ToLower(answer) == "y" || strings.ToLower(answer) == "yes" {
|
if strings.ToLower(answer) == "y" || strings.ToLower(answer) == "yes" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Errorf("won't proceed; the user didn't answer (Y|y) in order to continue")
|
return errors.New("won't proceed; the user didn't answer (Y|y) in order to continue")
|
||||||
}
|
}
|
||||||
|
@@ -17,11 +17,11 @@ limitations under the License.
|
|||||||
package upgrade
|
package upgrade
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
|
"github.com/pkg/errors"
|
||||||
"github.com/pmezard/go-difflib/difflib"
|
"github.com/pmezard/go-difflib/difflib"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
@@ -125,7 +125,7 @@ func runDiff(flags *diffFlags, args []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if path == "" {
|
if path == "" {
|
||||||
return fmt.Errorf("empty manifest path")
|
return errors.New("empty manifest path")
|
||||||
}
|
}
|
||||||
existingManifest, err := ioutil.ReadFile(path)
|
existingManifest, err := ioutil.ReadFile(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@@ -23,6 +23,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"k8s.io/apimachinery/pkg/util/version"
|
"k8s.io/apimachinery/pkg/util/version"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/options"
|
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/options"
|
||||||
@@ -157,7 +158,7 @@ func NewCmdUpgradeControlPlane() *cobra.Command {
|
|||||||
// RunUpgradeNodeConfig is executed when `kubeadm upgrade node config` runs.
|
// RunUpgradeNodeConfig is executed when `kubeadm upgrade node config` runs.
|
||||||
func RunUpgradeNodeConfig(flags *nodeUpgradeFlags) error {
|
func RunUpgradeNodeConfig(flags *nodeUpgradeFlags) error {
|
||||||
if len(flags.kubeletVersionStr) == 0 {
|
if len(flags.kubeletVersionStr) == 0 {
|
||||||
return fmt.Errorf("The --kubelet-version argument is required")
|
return errors.New("the --kubelet-version argument is required")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up the kubelet directory to use. If dry-running, use a fake directory
|
// Set up the kubelet directory to use. If dry-running, use a fake directory
|
||||||
@@ -168,7 +169,7 @@ func RunUpgradeNodeConfig(flags *nodeUpgradeFlags) error {
|
|||||||
|
|
||||||
client, err := getClient(flags.kubeConfigPath, flags.dryRun)
|
client, err := getClient(flags.kubeConfigPath, flags.dryRun)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("couldn't create a Kubernetes client from file %q: %v", flags.kubeConfigPath, err)
|
return errors.Wrapf(err, "couldn't create a Kubernetes client from file %q", flags.kubeConfigPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse the desired kubelet version
|
// Parse the desired kubelet version
|
||||||
@@ -183,7 +184,7 @@ func RunUpgradeNodeConfig(flags *nodeUpgradeFlags) error {
|
|||||||
|
|
||||||
// If we're dry-running, print the generated manifests, otherwise do nothing
|
// If we're dry-running, print the generated manifests, otherwise do nothing
|
||||||
if err := printFilesIfDryRunning(flags.dryRun, kubeletDir); err != nil {
|
if err := printFilesIfDryRunning(flags.dryRun, kubeletDir); err != nil {
|
||||||
return fmt.Errorf("error printing files on dryrun: %v", err)
|
return errors.Wrap(err, "error printing files on dryrun")
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("[upgrade] The configuration for this node was successfully updated!")
|
fmt.Println("[upgrade] The configuration for this node was successfully updated!")
|
||||||
@@ -196,7 +197,7 @@ func getKubeletDir(dryRun bool) (string, error) {
|
|||||||
if dryRun {
|
if dryRun {
|
||||||
dryRunDir, err := ioutil.TempDir("", "kubeadm-init-dryrun")
|
dryRunDir, err := ioutil.TempDir("", "kubeadm-init-dryrun")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("couldn't create a temporary directory: %v", err)
|
return "", errors.Wrap(err, "couldn't create a temporary directory")
|
||||||
}
|
}
|
||||||
return dryRunDir, nil
|
return dryRunDir, nil
|
||||||
}
|
}
|
||||||
@@ -222,7 +223,7 @@ func RunUpgradeControlPlane(flags *controlplaneUpgradeFlags) error {
|
|||||||
|
|
||||||
client, err := getClient(flags.kubeConfigPath, flags.dryRun)
|
client, err := getClient(flags.kubeConfigPath, flags.dryRun)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Couldn't create a Kubernetes client from file %q: %v", flags.kubeConfigPath, err)
|
return errors.Wrapf(err, "couldn't create a Kubernetes client from file %q", flags.kubeConfigPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
waiter := apiclient.NewKubeWaiter(client, upgrade.UpgradeManifestTimeout, os.Stdout)
|
waiter := apiclient.NewKubeWaiter(client, upgrade.UpgradeManifestTimeout, os.Stdout)
|
||||||
@@ -230,12 +231,12 @@ func RunUpgradeControlPlane(flags *controlplaneUpgradeFlags) error {
|
|||||||
// Fetches the cluster configuration
|
// Fetches the cluster configuration
|
||||||
cfg, err := configutil.FetchConfigFromFileOrCluster(client, os.Stdout, "upgrade", "", false)
|
cfg, err := configutil.FetchConfigFromFileOrCluster(client, os.Stdout, "upgrade", "", false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Unable to fetch the kubeadm-config ConfigMap: %v", err)
|
return errors.Wrap(err, "unable to fetch the kubeadm-config ConfigMap")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rotate API server certificate if needed
|
// Rotate API server certificate if needed
|
||||||
if err := upgrade.BackupAPIServerCertIfNeeded(cfg, flags.dryRun); err != nil {
|
if err := upgrade.BackupAPIServerCertIfNeeded(cfg, flags.dryRun); err != nil {
|
||||||
return fmt.Errorf("Unable to rotate API server certificate: %v", err)
|
return errors.Wrap(err, "unable to rotate API server certificate")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Upgrade the control plane and etcd if installed on this node
|
// Upgrade the control plane and etcd if installed on this node
|
||||||
@@ -245,7 +246,7 @@ func RunUpgradeControlPlane(flags *controlplaneUpgradeFlags) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err := PerformStaticPodUpgrade(client, waiter, cfg, flags.etcdUpgrade); err != nil {
|
if err := PerformStaticPodUpgrade(client, waiter, cfg, flags.etcdUpgrade); err != nil {
|
||||||
return fmt.Errorf("Couldn't complete the static pod upgrade: %v", err)
|
return errors.Wrap(err, "couldn't complete the static pod upgrade")
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("[upgrade] The control plane instance for this node was successfully updated!")
|
fmt.Println("[upgrade] The control plane instance for this node was successfully updated!")
|
||||||
|
@@ -25,6 +25,7 @@ import (
|
|||||||
"text/tabwriter"
|
"text/tabwriter"
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"k8s.io/apimachinery/pkg/util/version"
|
"k8s.io/apimachinery/pkg/util/version"
|
||||||
kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1"
|
kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1"
|
||||||
@@ -122,7 +123,7 @@ func RunPlan(flags *planFlags) error {
|
|||||||
glog.V(1).Infof("[upgrade/plan] computing upgrade possibilities")
|
glog.V(1).Infof("[upgrade/plan] computing upgrade possibilities")
|
||||||
availUpgrades, err := upgrade.GetAvailableUpgrades(upgradeVars.versionGetter, flags.allowExperimentalUpgrades, flags.allowRCUpgrades, etcdClient, upgradeVars.cfg.FeatureGates, upgradeVars.client)
|
availUpgrades, err := upgrade.GetAvailableUpgrades(upgradeVars.versionGetter, flags.allowExperimentalUpgrades, flags.allowRCUpgrades, etcdClient, upgradeVars.cfg.FeatureGates, upgradeVars.client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("[upgrade/versions] FATAL: %v", err)
|
return errors.Wrap(err, "[upgrade/versions] FATAL")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tell the user which upgrades are available
|
// Tell the user which upgrades are available
|
||||||
|
@@ -17,8 +17,7 @@ limitations under the License.
|
|||||||
package util
|
package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"k8s.io/client-go/tools/clientcmd"
|
"k8s.io/client-go/tools/clientcmd"
|
||||||
@@ -33,10 +32,10 @@ import (
|
|||||||
func SubCmdRunE(name string) func(*cobra.Command, []string) error {
|
func SubCmdRunE(name string) func(*cobra.Command, []string) error {
|
||||||
return func(_ *cobra.Command, args []string) error {
|
return func(_ *cobra.Command, args []string) error {
|
||||||
if len(args) < 1 {
|
if len(args) < 1 {
|
||||||
return fmt.Errorf("missing subcommand; %q is not meant to be run on its own", name)
|
return errors.Errorf("missing subcommand; %q is not meant to be run on its own", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Errorf("invalid subcommand: %q", args[0])
|
return errors.Errorf("invalid subcommand: %q", args[0])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,12 +50,12 @@ func ValidateExactArgNumber(args []string, supportedArgs []string) error {
|
|||||||
}
|
}
|
||||||
// break early for too many arguments
|
// break early for too many arguments
|
||||||
if validArgs > lenSupported {
|
if validArgs > lenSupported {
|
||||||
return fmt.Errorf("too many arguments. Required arguments: %v", supportedArgs)
|
return errors.Errorf("too many arguments. Required arguments: %v", supportedArgs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if validArgs < lenSupported {
|
if validArgs < lenSupported {
|
||||||
return fmt.Errorf("missing one or more required arguments. Required arguments: %v", supportedArgs)
|
return errors.Errorf("missing one or more required arguments. Required arguments: %v", supportedArgs)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@@ -19,10 +19,10 @@ package util
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"fmt"
|
|
||||||
"html/template"
|
"html/template"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
"k8s.io/client-go/tools/clientcmd"
|
"k8s.io/client-go/tools/clientcmd"
|
||||||
clientcertutil "k8s.io/client-go/util/cert"
|
clientcertutil "k8s.io/client-go/util/cert"
|
||||||
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
|
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
|
||||||
@@ -39,13 +39,13 @@ func GetJoinCommand(kubeConfigFile string, token string, skipTokenPrint bool) (s
|
|||||||
// load the kubeconfig file to get the CA certificate and endpoint
|
// load the kubeconfig file to get the CA certificate and endpoint
|
||||||
config, err := clientcmd.LoadFromFile(kubeConfigFile)
|
config, err := clientcmd.LoadFromFile(kubeConfigFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("failed to load kubeconfig: %v", err)
|
return "", errors.Wrap(err, "failed to load kubeconfig")
|
||||||
}
|
}
|
||||||
|
|
||||||
// load the default cluster config
|
// load the default cluster config
|
||||||
clusterConfig := kubeconfigutil.GetClusterFromKubeConfig(config)
|
clusterConfig := kubeconfigutil.GetClusterFromKubeConfig(config)
|
||||||
if clusterConfig == nil {
|
if clusterConfig == nil {
|
||||||
return "", fmt.Errorf("failed to get default cluster config")
|
return "", errors.New("failed to get default cluster config")
|
||||||
}
|
}
|
||||||
|
|
||||||
// load CA certificates from the kubeconfig (either from PEM data or by file path)
|
// load CA certificates from the kubeconfig (either from PEM data or by file path)
|
||||||
@@ -53,15 +53,15 @@ func GetJoinCommand(kubeConfigFile string, token string, skipTokenPrint bool) (s
|
|||||||
if clusterConfig.CertificateAuthorityData != nil {
|
if clusterConfig.CertificateAuthorityData != nil {
|
||||||
caCerts, err = clientcertutil.ParseCertsPEM(clusterConfig.CertificateAuthorityData)
|
caCerts, err = clientcertutil.ParseCertsPEM(clusterConfig.CertificateAuthorityData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("failed to parse CA certificate from kubeconfig: %v", err)
|
return "", errors.Wrap(err, "failed to parse CA certificate from kubeconfig")
|
||||||
}
|
}
|
||||||
} else if clusterConfig.CertificateAuthority != "" {
|
} else if clusterConfig.CertificateAuthority != "" {
|
||||||
caCerts, err = clientcertutil.CertsFromFile(clusterConfig.CertificateAuthority)
|
caCerts, err = clientcertutil.CertsFromFile(clusterConfig.CertificateAuthority)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("failed to load CA certificate referenced by kubeconfig: %v", err)
|
return "", errors.Wrap(err, "failed to load CA certificate referenced by kubeconfig")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return "", fmt.Errorf("no CA certificates found in kubeconfig")
|
return "", errors.New("no CA certificates found in kubeconfig")
|
||||||
}
|
}
|
||||||
|
|
||||||
// hash all the CA certs and include their public key pins as trusted values
|
// hash all the CA certs and include their public key pins as trusted values
|
||||||
@@ -83,7 +83,7 @@ func GetJoinCommand(kubeConfigFile string, token string, skipTokenPrint bool) (s
|
|||||||
var out bytes.Buffer
|
var out bytes.Buffer
|
||||||
err = joinCommandTemplate.Execute(&out, ctx)
|
err = joinCommandTemplate.Execute(&out, ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("failed to render join command template: %v", err)
|
return "", errors.Wrap(err, "failed to render join command template")
|
||||||
}
|
}
|
||||||
return out.String(), nil
|
return out.String(), nil
|
||||||
}
|
}
|
||||||
|
@@ -23,6 +23,7 @@ import (
|
|||||||
|
|
||||||
"github.com/ghodss/yaml"
|
"github.com/ghodss/yaml"
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
apimachineryversion "k8s.io/apimachinery/pkg/version"
|
apimachineryversion "k8s.io/apimachinery/pkg/version"
|
||||||
@@ -82,7 +83,7 @@ func RunVersion(out io.Writer, cmd *cobra.Command) error {
|
|||||||
}
|
}
|
||||||
fmt.Fprintln(out, string(y))
|
fmt.Fprintln(out, string(y))
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("invalid output format: %s", of)
|
return errors.Errorf("invalid output format: %s", of)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@@ -19,8 +19,8 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
"github.com/ghodss/yaml"
|
"github.com/ghodss/yaml"
|
||||||
|
"github.com/pkg/errors"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -80,7 +80,7 @@ func TestRunVersion(t *testing.T) {
|
|||||||
goto error
|
goto error
|
||||||
}
|
}
|
||||||
if buf.String() == "" {
|
if buf.String() == "" {
|
||||||
err = fmt.Errorf("empty output")
|
err = errors.New("empty output")
|
||||||
goto error
|
goto error
|
||||||
}
|
}
|
||||||
if tc.shouldBeValidYAML {
|
if tc.shouldBeValidYAML {
|
||||||
|
@@ -17,7 +17,7 @@ limitations under the License.
|
|||||||
package componentconfigs
|
package componentconfigs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
@@ -41,7 +41,8 @@ func GetFromKubeletConfigMap(client clientset.Interface, version *version.Versio
|
|||||||
|
|
||||||
kubeletConfigData, ok := kubeletCfg.Data[kubeadmconstants.KubeletBaseConfigurationConfigMapKey]
|
kubeletConfigData, ok := kubeletCfg.Data[kubeadmconstants.KubeletBaseConfigurationConfigMapKey]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("unexpected error when reading %s ConfigMap: %s key value pair missing", configMapName, kubeadmconstants.KubeletBaseConfigurationConfigMapKey)
|
return nil, errors.Errorf("unexpected error when reading %s ConfigMap: %s key value pair missing",
|
||||||
|
configMapName, kubeadmconstants.KubeletBaseConfigurationConfigMapKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decodes the kubeletConfigData into the internal component config
|
// Decodes the kubeletConfigData into the internal component config
|
||||||
@@ -66,7 +67,8 @@ func GetFromKubeProxyConfigMap(client clientset.Interface, version *version.Vers
|
|||||||
|
|
||||||
kubeproxyConfigData, ok := kubeproxyCfg.Data[kubeadmconstants.KubeProxyConfigMapKey]
|
kubeproxyConfigData, ok := kubeproxyCfg.Data[kubeadmconstants.KubeProxyConfigMapKey]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("unexpected error when reading %s ConfigMap: %s key value pair missing", kubeadmconstants.KubeProxyConfigMap, kubeadmconstants.KubeProxyConfigMapKey)
|
return nil, errors.Errorf("unexpected error when reading %s ConfigMap: %s key value pair missing",
|
||||||
|
kubeadmconstants.KubeProxyConfigMap, kubeadmconstants.KubeProxyConfigMapKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decodes the Config map dat into the internal component config
|
// Decodes the Config map dat into the internal component config
|
||||||
|
@@ -17,9 +17,10 @@ limitations under the License.
|
|||||||
package discovery
|
package discovery
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/discovery/file"
|
"k8s.io/kubernetes/cmd/kubeadm/app/discovery/file"
|
||||||
@@ -38,7 +39,7 @@ func For(cfg *kubeadmapi.JoinConfiguration) (*clientcmdapi.Config, error) {
|
|||||||
// we also need an ability for the user to configure the client to validate received CA cert against a checksum
|
// we also need an ability for the user to configure the client to validate received CA cert against a checksum
|
||||||
config, err := DiscoverValidatedKubeConfig(cfg)
|
config, err := DiscoverValidatedKubeConfig(cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("couldn't validate the identity of the API Server: %v", err)
|
return nil, errors.Wrap(err, "couldn't validate the identity of the API Server")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(cfg.Discovery.TLSBootstrapToken) == 0 {
|
if len(cfg.Discovery.TLSBootstrapToken) == 0 {
|
||||||
@@ -66,7 +67,7 @@ func DiscoverValidatedKubeConfig(cfg *kubeadmapi.JoinConfiguration) (*clientcmda
|
|||||||
case cfg.Discovery.BootstrapToken != nil:
|
case cfg.Discovery.BootstrapToken != nil:
|
||||||
return token.RetrieveValidatedConfigInfo(cfg)
|
return token.RetrieveValidatedConfigInfo(cfg)
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("couldn't find a valid discovery configuration")
|
return nil, errors.New("couldn't find a valid discovery configuration")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -19,6 +19,9 @@ package file
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
@@ -66,7 +69,7 @@ func ValidateConfigInfo(config *clientcmdapi.Config, clustername string) (*clien
|
|||||||
user := config.Contexts[config.CurrentContext].AuthInfo
|
user := config.Contexts[config.CurrentContext].AuthInfo
|
||||||
authInfo, ok := config.AuthInfos[user]
|
authInfo, ok := config.AuthInfos[user]
|
||||||
if !ok || authInfo == nil {
|
if !ok || authInfo == nil {
|
||||||
return nil, fmt.Errorf("empty settings for user %q", user)
|
return nil, errors.Errorf("empty settings for user %q", user)
|
||||||
}
|
}
|
||||||
if len(authInfo.ClientCertificateData) == 0 && len(authInfo.ClientCertificate) != 0 {
|
if len(authInfo.ClientCertificateData) == 0 && len(authInfo.ClientCertificate) != 0 {
|
||||||
clientCert, err := ioutil.ReadFile(authInfo.ClientCertificate)
|
clientCert, err := ioutil.ReadFile(authInfo.ClientCertificate)
|
||||||
@@ -84,7 +87,7 @@ func ValidateConfigInfo(config *clientcmdapi.Config, clustername string) (*clien
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(authInfo.ClientCertificateData) == 0 || len(authInfo.ClientKeyData) == 0 {
|
if len(authInfo.ClientCertificateData) == 0 || len(authInfo.ClientKeyData) == 0 {
|
||||||
return nil, fmt.Errorf("couldn't read authentication info from the given kubeconfig file")
|
return nil, errors.New("couldn't read authentication info from the given kubeconfig file")
|
||||||
}
|
}
|
||||||
kubeconfig = kubeconfigutil.CreateWithCerts(
|
kubeconfig = kubeconfigutil.CreateWithCerts(
|
||||||
defaultCluster.Server,
|
defaultCluster.Server,
|
||||||
@@ -141,11 +144,11 @@ func ValidateConfigInfo(config *clientcmdapi.Config, clustername string) (*clien
|
|||||||
func tryParseClusterInfoFromConfigMap(cm *v1.ConfigMap) (*clientcmdapi.Config, error) {
|
func tryParseClusterInfoFromConfigMap(cm *v1.ConfigMap) (*clientcmdapi.Config, error) {
|
||||||
kubeConfigString, ok := cm.Data[bootstrapapi.KubeConfigKey]
|
kubeConfigString, ok := cm.Data[bootstrapapi.KubeConfigKey]
|
||||||
if !ok || len(kubeConfigString) == 0 {
|
if !ok || len(kubeConfigString) == 0 {
|
||||||
return nil, fmt.Errorf("no %s key in ConfigMap", bootstrapapi.KubeConfigKey)
|
return nil, errors.Errorf("no %s key in ConfigMap", bootstrapapi.KubeConfigKey)
|
||||||
}
|
}
|
||||||
parsedKubeConfig, err := clientcmd.Load([]byte(kubeConfigString))
|
parsedKubeConfig, err := clientcmd.Load([]byte(kubeConfigString))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("couldn't parse the kubeconfig file in the %s ConfigMap: %v", bootstrapapi.ConfigMapClusterInfo, err)
|
return nil, errors.Wrapf(err, "couldn't parse the kubeconfig file in the %s ConfigMap", bootstrapapi.ConfigMapClusterInfo)
|
||||||
}
|
}
|
||||||
return parsedKubeConfig, nil
|
return parsedKubeConfig, nil
|
||||||
}
|
}
|
||||||
@@ -153,11 +156,11 @@ func tryParseClusterInfoFromConfigMap(cm *v1.ConfigMap) (*clientcmdapi.Config, e
|
|||||||
// validateKubeConfig makes sure the user-provided KubeConfig file is valid
|
// validateKubeConfig makes sure the user-provided KubeConfig file is valid
|
||||||
func validateKubeConfig(config *clientcmdapi.Config) error {
|
func validateKubeConfig(config *clientcmdapi.Config) error {
|
||||||
if len(config.Clusters) < 1 {
|
if len(config.Clusters) < 1 {
|
||||||
return fmt.Errorf("the provided cluster-info KubeConfig file must have at least one Cluster defined")
|
return errors.New("the provided cluster-info KubeConfig file must have at least one Cluster defined")
|
||||||
}
|
}
|
||||||
defaultCluster := kubeconfigutil.GetClusterFromKubeConfig(config)
|
defaultCluster := kubeconfigutil.GetClusterFromKubeConfig(config)
|
||||||
if defaultCluster == nil {
|
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 errors.New("the provided cluster-info KubeConfig file must have an unnamed Cluster or a CurrentContext that specifies a non-nil Cluster")
|
||||||
}
|
}
|
||||||
return clientcmd.Validate(*config)
|
return clientcmd.Validate(*config)
|
||||||
}
|
}
|
||||||
|
@@ -24,6 +24,8 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
@@ -85,19 +87,20 @@ func RetrieveValidatedConfigInfo(cfg *kubeadmapi.JoinConfiguration) (*clientcmda
|
|||||||
// Validate the MAC on the kubeconfig from the ConfigMap and load it
|
// Validate the MAC on the kubeconfig from the ConfigMap and load it
|
||||||
insecureKubeconfigString, ok := insecureClusterInfo.Data[bootstrapapi.KubeConfigKey]
|
insecureKubeconfigString, ok := insecureClusterInfo.Data[bootstrapapi.KubeConfigKey]
|
||||||
if !ok || len(insecureKubeconfigString) == 0 {
|
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)
|
return nil, errors.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+token.ID]
|
detachedJWSToken, ok := insecureClusterInfo.Data[bootstrapapi.JWSSignatureKeyPrefix+token.ID]
|
||||||
if !ok || len(detachedJWSToken) == 0 {
|
if !ok || len(detachedJWSToken) == 0 {
|
||||||
return nil, fmt.Errorf("token id %q is invalid for this cluster or it has expired. Use \"kubeadm token create\" on the master node to creating a new valid token", token.ID)
|
return nil, errors.Errorf("token id %q is invalid for this cluster or it has expired. Use \"kubeadm token create\" on the master node to creating a new valid token", token.ID)
|
||||||
}
|
}
|
||||||
if !bootstrap.DetachedTokenIsValid(detachedJWSToken, insecureKubeconfigString, token.ID, token.Secret) {
|
if !bootstrap.DetachedTokenIsValid(detachedJWSToken, insecureKubeconfigString, token.ID, token.Secret) {
|
||||||
return nil, fmt.Errorf("failed to verify JWS signature of received cluster info object, can't trust this API Server")
|
return nil, errors.New("failed to verify JWS signature of received cluster info object, can't trust this API Server")
|
||||||
}
|
}
|
||||||
insecureKubeconfigBytes := []byte(insecureKubeconfigString)
|
insecureKubeconfigBytes := []byte(insecureKubeconfigString)
|
||||||
insecureConfig, err := clientcmd.Load(insecureKubeconfigBytes)
|
insecureConfig, err := clientcmd.Load(insecureKubeconfigBytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("couldn't parse the kubeconfig file in the %s configmap: %v", bootstrapapi.ConfigMapClusterInfo, err)
|
return nil, errors.Wrapf(err, "couldn't parse the kubeconfig file in the %s configmap", bootstrapapi.ConfigMapClusterInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no TLS root CA pinning was specified, we're done
|
// If no TLS root CA pinning was specified, we're done
|
||||||
@@ -108,7 +111,7 @@ func RetrieveValidatedConfigInfo(cfg *kubeadmapi.JoinConfiguration) (*clientcmda
|
|||||||
|
|
||||||
// Load the cluster CA from the Config
|
// Load the cluster CA from the Config
|
||||||
if len(insecureConfig.Clusters) != 1 {
|
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))
|
return nil, errors.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
|
var clusterCABytes []byte
|
||||||
for _, cluster := range insecureConfig.Clusters {
|
for _, cluster := range insecureConfig.Clusters {
|
||||||
@@ -116,14 +119,14 @@ func RetrieveValidatedConfigInfo(cfg *kubeadmapi.JoinConfiguration) (*clientcmda
|
|||||||
}
|
}
|
||||||
clusterCA, err := parsePEMCert(clusterCABytes)
|
clusterCA, err := parsePEMCert(clusterCABytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to parse cluster CA from the %s configmap: %v", bootstrapapi.ConfigMapClusterInfo, err)
|
return nil, errors.Wrapf(err, "failed to parse cluster CA from the %s configmap", bootstrapapi.ConfigMapClusterInfo)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate the cluster CA public key against the pinned set
|
// Validate the cluster CA public key against the pinned set
|
||||||
err = pubKeyPins.Check(clusterCA)
|
err = pubKeyPins.Check(clusterCA)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cluster CA found in %s configmap is invalid: %v", bootstrapapi.ConfigMapClusterInfo, err)
|
return nil, errors.Wrapf(err, "cluster CA found in %s configmap is invalid", bootstrapapi.ConfigMapClusterInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now that we know the proported cluster CA, connect back a second time validating with that CA
|
// Now that we know the proported cluster CA, connect back a second time validating with that CA
|
||||||
@@ -148,12 +151,12 @@ func RetrieveValidatedConfigInfo(cfg *kubeadmapi.JoinConfiguration) (*clientcmda
|
|||||||
// Pull the kubeconfig from the securely-obtained ConfigMap and validate that it's the same as what we found the first time
|
// 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])
|
secureKubeconfigBytes := []byte(secureClusterInfo.Data[bootstrapapi.KubeConfigKey])
|
||||||
if !bytes.Equal(secureKubeconfigBytes, insecureKubeconfigBytes) {
|
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)
|
return nil, errors.Errorf("the second kubeconfig from the %s configmap (using validated TLS) was different from the first", bootstrapapi.ConfigMapClusterInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
secureKubeconfig, err := clientcmd.Load(secureKubeconfigBytes)
|
secureKubeconfig, err := clientcmd.Load(secureKubeconfigBytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("couldn't parse the kubeconfig file in the %s configmap: %v", bootstrapapi.ConfigMapClusterInfo, err)
|
return nil, errors.Wrapf(err, "couldn't parse the kubeconfig file in the %s configmap", bootstrapapi.ConfigMapClusterInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("[discovery] Cluster info signature and contents are valid and TLS certificate validates against pinned roots, will use API Server %q\n", endpoint)
|
fmt.Printf("[discovery] Cluster info signature and contents are valid and TLS certificate validates against pinned roots, will use API Server %q\n", endpoint)
|
||||||
@@ -211,7 +214,7 @@ func runForEndpointsAndReturnFirst(endpoints []string, discoveryTimeout time.Dur
|
|||||||
select {
|
select {
|
||||||
case <-time.After(discoveryTimeout):
|
case <-time.After(discoveryTimeout):
|
||||||
close(stopChan)
|
close(stopChan)
|
||||||
err := fmt.Errorf("abort connecting to API servers after timeout of %v", discoveryTimeout)
|
err := errors.Errorf("abort connecting to API servers after timeout of %v", discoveryTimeout)
|
||||||
fmt.Printf("[discovery] %v\n", err)
|
fmt.Printf("[discovery] %v\n", err)
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -225,10 +228,10 @@ func runForEndpointsAndReturnFirst(endpoints []string, discoveryTimeout time.Dur
|
|||||||
func parsePEMCert(certData []byte) (*x509.Certificate, error) {
|
func parsePEMCert(certData []byte) (*x509.Certificate, error) {
|
||||||
pemBlock, trailingData := pem.Decode(certData)
|
pemBlock, trailingData := pem.Decode(certData)
|
||||||
if pemBlock == nil {
|
if pemBlock == nil {
|
||||||
return nil, fmt.Errorf("invalid PEM data")
|
return nil, errors.New("invalid PEM data")
|
||||||
}
|
}
|
||||||
if len(trailingData) != 0 {
|
if len(trailingData) != 0 {
|
||||||
return nil, fmt.Errorf("trailing data after first PEM block")
|
return nil, errors.New("trailing data after first PEM block")
|
||||||
}
|
}
|
||||||
return x509.ParseCertificate(pemBlock.Bytes)
|
return x509.ParseCertificate(pemBlock.Bytes)
|
||||||
}
|
}
|
||||||
|
@@ -22,6 +22,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/mholt/caddy/caddyfile"
|
"github.com/mholt/caddy/caddyfile"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
apps "k8s.io/api/apps/v1"
|
apps "k8s.io/api/apps/v1"
|
||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
@@ -51,7 +52,7 @@ func DeployedDNSAddon(client clientset.Interface) (string, string, error) {
|
|||||||
deploymentsClient := client.AppsV1().Deployments(metav1.NamespaceSystem)
|
deploymentsClient := client.AppsV1().Deployments(metav1.NamespaceSystem)
|
||||||
deployments, err := deploymentsClient.List(metav1.ListOptions{LabelSelector: "k8s-app=kube-dns"})
|
deployments, err := deploymentsClient.List(metav1.ListOptions{LabelSelector: "k8s-app=kube-dns"})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", fmt.Errorf("couldn't retrieve DNS addon deployments: %v", err)
|
return "", "", errors.Wrap(err, "couldn't retrieve DNS addon deployments")
|
||||||
}
|
}
|
||||||
|
|
||||||
switch len(deployments.Items) {
|
switch len(deployments.Items) {
|
||||||
@@ -64,7 +65,7 @@ func DeployedDNSAddon(client clientset.Interface) (string, string, error) {
|
|||||||
addonVersion := addonImageParts[len(addonImageParts)-1]
|
addonVersion := addonImageParts[len(addonImageParts)-1]
|
||||||
return addonName, addonVersion, nil
|
return addonName, addonVersion, nil
|
||||||
default:
|
default:
|
||||||
return "", "", fmt.Errorf("multiple DNS addon deployments found: %v", deployments.Items)
|
return "", "", errors.Errorf("multiple DNS addon deployments found: %v", deployments.Items)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,14 +106,14 @@ func kubeDNSAddon(cfg *kubeadmapi.InitConfiguration, client clientset.Interface)
|
|||||||
MasterTaintKey: kubeadmconstants.LabelNodeRoleMaster,
|
MasterTaintKey: kubeadmconstants.LabelNodeRoleMaster,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error when parsing kube-dns deployment template: %v", err)
|
return errors.Wrap(err, "error when parsing kube-dns deployment template")
|
||||||
}
|
}
|
||||||
|
|
||||||
dnsServiceBytes, err := kubeadmutil.ParseTemplate(KubeDNSService, struct{ DNSIP string }{
|
dnsServiceBytes, err := kubeadmutil.ParseTemplate(KubeDNSService, struct{ DNSIP string }{
|
||||||
DNSIP: dnsip.String(),
|
DNSIP: dnsip.String(),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error when parsing kube-proxy configmap template: %v", err)
|
return errors.Wrap(err, "error when parsing kube-proxy configmap template")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := createKubeDNSAddon(dnsDeploymentBytes, dnsServiceBytes, client); err != nil {
|
if err := createKubeDNSAddon(dnsDeploymentBytes, dnsServiceBytes, client); err != nil {
|
||||||
@@ -136,7 +137,7 @@ func CreateServiceAccount(client clientset.Interface) error {
|
|||||||
func createKubeDNSAddon(deploymentBytes, serviceBytes []byte, client clientset.Interface) error {
|
func createKubeDNSAddon(deploymentBytes, serviceBytes []byte, client clientset.Interface) error {
|
||||||
kubednsDeployment := &apps.Deployment{}
|
kubednsDeployment := &apps.Deployment{}
|
||||||
if err := kuberuntime.DecodeInto(clientsetscheme.Codecs.UniversalDecoder(), deploymentBytes, kubednsDeployment); err != nil {
|
if err := kuberuntime.DecodeInto(clientsetscheme.Codecs.UniversalDecoder(), deploymentBytes, kubednsDeployment); err != nil {
|
||||||
return fmt.Errorf("unable to decode kube-dns deployment %v", err)
|
return errors.Wrap(err, "unable to decode kube-dns deployment")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the Deployment for kube-dns or update it in case it already exists
|
// Create the Deployment for kube-dns or update it in case it already exists
|
||||||
@@ -156,7 +157,7 @@ func coreDNSAddon(cfg *kubeadmapi.InitConfiguration, client clientset.Interface)
|
|||||||
Version: kubeadmconstants.CoreDNSVersion,
|
Version: kubeadmconstants.CoreDNSVersion,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error when parsing CoreDNS deployment template: %v", err)
|
return errors.Wrap(err, "error when parsing CoreDNS deployment template")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the kube-dns ConfigMap for translation to equivalent CoreDNS Config.
|
// Get the kube-dns ConfigMap for translation to equivalent CoreDNS Config.
|
||||||
@@ -188,7 +189,7 @@ func coreDNSAddon(cfg *kubeadmapi.InitConfiguration, client clientset.Interface)
|
|||||||
StubDomain: stubDomain,
|
StubDomain: stubDomain,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error when parsing CoreDNS configMap template: %v", err)
|
return errors.Wrap(err, "error when parsing CoreDNS configMap template")
|
||||||
}
|
}
|
||||||
|
|
||||||
dnsip, err := kubeadmconstants.GetDNSIP(cfg.Networking.ServiceSubnet)
|
dnsip, err := kubeadmconstants.GetDNSIP(cfg.Networking.ServiceSubnet)
|
||||||
@@ -201,7 +202,7 @@ func coreDNSAddon(cfg *kubeadmapi.InitConfiguration, client clientset.Interface)
|
|||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error when parsing CoreDNS service template: %v", err)
|
return errors.Wrap(err, "error when parsing CoreDNS service template")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := createCoreDNSAddon(coreDNSDeploymentBytes, coreDNSServiceBytes, coreDNSConfigMapBytes, client); err != nil {
|
if err := createCoreDNSAddon(coreDNSDeploymentBytes, coreDNSServiceBytes, coreDNSConfigMapBytes, client); err != nil {
|
||||||
@@ -214,7 +215,7 @@ func coreDNSAddon(cfg *kubeadmapi.InitConfiguration, client clientset.Interface)
|
|||||||
func createCoreDNSAddon(deploymentBytes, serviceBytes, configBytes []byte, client clientset.Interface) error {
|
func createCoreDNSAddon(deploymentBytes, serviceBytes, configBytes []byte, client clientset.Interface) error {
|
||||||
coreDNSConfigMap := &v1.ConfigMap{}
|
coreDNSConfigMap := &v1.ConfigMap{}
|
||||||
if err := kuberuntime.DecodeInto(clientsetscheme.Codecs.UniversalDecoder(), configBytes, coreDNSConfigMap); err != nil {
|
if err := kuberuntime.DecodeInto(clientsetscheme.Codecs.UniversalDecoder(), configBytes, coreDNSConfigMap); err != nil {
|
||||||
return fmt.Errorf("unable to decode CoreDNS configmap %v", err)
|
return errors.Wrap(err, "unable to decode CoreDNS configmap")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the ConfigMap for CoreDNS or retain it in case it already exists
|
// Create the ConfigMap for CoreDNS or retain it in case it already exists
|
||||||
@@ -224,7 +225,7 @@ func createCoreDNSAddon(deploymentBytes, serviceBytes, configBytes []byte, clien
|
|||||||
|
|
||||||
coreDNSClusterRoles := &rbac.ClusterRole{}
|
coreDNSClusterRoles := &rbac.ClusterRole{}
|
||||||
if err := kuberuntime.DecodeInto(clientsetscheme.Codecs.UniversalDecoder(), []byte(CoreDNSClusterRole), coreDNSClusterRoles); err != nil {
|
if err := kuberuntime.DecodeInto(clientsetscheme.Codecs.UniversalDecoder(), []byte(CoreDNSClusterRole), coreDNSClusterRoles); err != nil {
|
||||||
return fmt.Errorf("unable to decode CoreDNS clusterroles %v", err)
|
return errors.Wrap(err, "unable to decode CoreDNS clusterroles")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the Clusterroles for CoreDNS or update it in case it already exists
|
// Create the Clusterroles for CoreDNS or update it in case it already exists
|
||||||
@@ -234,7 +235,7 @@ func createCoreDNSAddon(deploymentBytes, serviceBytes, configBytes []byte, clien
|
|||||||
|
|
||||||
coreDNSClusterRolesBinding := &rbac.ClusterRoleBinding{}
|
coreDNSClusterRolesBinding := &rbac.ClusterRoleBinding{}
|
||||||
if err := kuberuntime.DecodeInto(clientsetscheme.Codecs.UniversalDecoder(), []byte(CoreDNSClusterRoleBinding), coreDNSClusterRolesBinding); err != nil {
|
if err := kuberuntime.DecodeInto(clientsetscheme.Codecs.UniversalDecoder(), []byte(CoreDNSClusterRoleBinding), coreDNSClusterRolesBinding); err != nil {
|
||||||
return fmt.Errorf("unable to decode CoreDNS clusterrolebindings %v", err)
|
return errors.Wrap(err, "unable to decode CoreDNS clusterrolebindings")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the Clusterrolebindings for CoreDNS or update it in case it already exists
|
// Create the Clusterrolebindings for CoreDNS or update it in case it already exists
|
||||||
@@ -244,7 +245,7 @@ func createCoreDNSAddon(deploymentBytes, serviceBytes, configBytes []byte, clien
|
|||||||
|
|
||||||
coreDNSServiceAccount := &v1.ServiceAccount{}
|
coreDNSServiceAccount := &v1.ServiceAccount{}
|
||||||
if err := kuberuntime.DecodeInto(clientsetscheme.Codecs.UniversalDecoder(), []byte(CoreDNSServiceAccount), coreDNSServiceAccount); err != nil {
|
if err := kuberuntime.DecodeInto(clientsetscheme.Codecs.UniversalDecoder(), []byte(CoreDNSServiceAccount), coreDNSServiceAccount); err != nil {
|
||||||
return fmt.Errorf("unable to decode CoreDNS serviceaccount %v", err)
|
return errors.Wrap(err, "unable to decode CoreDNS serviceaccount")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the ConfigMap for CoreDNS or update it in case it already exists
|
// Create the ConfigMap for CoreDNS or update it in case it already exists
|
||||||
@@ -254,7 +255,7 @@ func createCoreDNSAddon(deploymentBytes, serviceBytes, configBytes []byte, clien
|
|||||||
|
|
||||||
coreDNSDeployment := &apps.Deployment{}
|
coreDNSDeployment := &apps.Deployment{}
|
||||||
if err := kuberuntime.DecodeInto(clientsetscheme.Codecs.UniversalDecoder(), deploymentBytes, coreDNSDeployment); err != nil {
|
if err := kuberuntime.DecodeInto(clientsetscheme.Codecs.UniversalDecoder(), deploymentBytes, coreDNSDeployment); err != nil {
|
||||||
return fmt.Errorf("unable to decode CoreDNS deployment %v", err)
|
return errors.Wrap(err, "unable to decode CoreDNS deployment")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the Deployment for CoreDNS or update it in case it already exists
|
// Create the Deployment for CoreDNS or update it in case it already exists
|
||||||
@@ -268,7 +269,7 @@ func createCoreDNSAddon(deploymentBytes, serviceBytes, configBytes []byte, clien
|
|||||||
|
|
||||||
func createDNSService(dnsService *v1.Service, serviceBytes []byte, client clientset.Interface) error {
|
func createDNSService(dnsService *v1.Service, serviceBytes []byte, client clientset.Interface) error {
|
||||||
if err := kuberuntime.DecodeInto(clientsetscheme.Codecs.UniversalDecoder(), serviceBytes, dnsService); err != nil {
|
if err := kuberuntime.DecodeInto(clientsetscheme.Codecs.UniversalDecoder(), serviceBytes, dnsService); err != nil {
|
||||||
return fmt.Errorf("unable to decode the DNS service %v", err)
|
return errors.Wrap(err, "unable to decode the DNS service")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Can't use a generic apiclient helper func here as we have to tolerate more than AlreadyExists.
|
// Can't use a generic apiclient helper func here as we have to tolerate more than AlreadyExists.
|
||||||
@@ -277,11 +278,11 @@ func createDNSService(dnsService *v1.Service, serviceBytes []byte, client client
|
|||||||
// Service "kube-dns" is invalid: spec.clusterIP: Invalid value: "10.96.0.10": provided IP is already allocated
|
// 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) {
|
if !apierrors.IsAlreadyExists(err) && !apierrors.IsInvalid(err) {
|
||||||
return fmt.Errorf("unable to create a new DNS service: %v", err)
|
return errors.Wrap(err, "unable to create a new DNS service")
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := client.CoreV1().Services(metav1.NamespaceSystem).Update(dnsService); err != nil {
|
if _, err := client.CoreV1().Services(metav1.NamespaceSystem).Update(dnsService); err != nil {
|
||||||
return fmt.Errorf("unable to create/update the DNS service: %v", err)
|
return errors.Wrap(err, "unable to create/update the DNS service")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -298,7 +299,7 @@ func translateStubDomainOfKubeDNSToProxyCoreDNS(dataField string, kubeDNSConfigM
|
|||||||
stubDomainData := make(map[string][]string)
|
stubDomainData := make(map[string][]string)
|
||||||
err := json.Unmarshal([]byte(proxy), &stubDomainData)
|
err := json.Unmarshal([]byte(proxy), &stubDomainData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("failed to parse JSON from 'kube-dns ConfigMap: %v", err)
|
return "", errors.Wrap(err, "failed to parse JSON from 'kube-dns ConfigMap")
|
||||||
}
|
}
|
||||||
|
|
||||||
var proxyStanza []interface{}
|
var proxyStanza []interface{}
|
||||||
@@ -340,7 +341,7 @@ func translateUpstreamNameServerOfKubeDNSToUpstreamProxyCoreDNS(dataField string
|
|||||||
|
|
||||||
err := json.Unmarshal([]byte(upstreamValues), &upstreamProxyIP)
|
err := json.Unmarshal([]byte(upstreamValues), &upstreamProxyIP)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("failed to parse JSON from 'kube-dns ConfigMap: %v", err)
|
return "", errors.Wrap(err, "failed to parse JSON from 'kube-dns ConfigMap")
|
||||||
}
|
}
|
||||||
|
|
||||||
coreDNSProxyStanzaList := strings.Join(upstreamProxyIP, " ")
|
coreDNSProxyStanzaList := strings.Join(upstreamProxyIP, " ")
|
||||||
@@ -365,7 +366,7 @@ func translateFederationsofKubeDNSToCoreDNS(dataField, coreDNSDomain string, kub
|
|||||||
|
|
||||||
err := json.Unmarshal([]byte(federation), &federationData)
|
err := json.Unmarshal([]byte(federation), &federationData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("failed to parse JSON from kube-dns ConfigMap: %v", err)
|
return "", errors.Wrap(err, "failed to parse JSON from kube-dns ConfigMap")
|
||||||
}
|
}
|
||||||
fStanza := map[string]interface{}{}
|
fStanza := map[string]interface{}{}
|
||||||
|
|
||||||
|
@@ -20,6 +20,8 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
apps "k8s.io/api/apps/v1"
|
apps "k8s.io/api/apps/v1"
|
||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
rbac "k8s.io/api/rbac/v1"
|
rbac "k8s.io/api/rbac/v1"
|
||||||
@@ -48,7 +50,7 @@ const (
|
|||||||
// EnsureProxyAddon creates the kube-proxy addons
|
// EnsureProxyAddon creates the kube-proxy addons
|
||||||
func EnsureProxyAddon(cfg *kubeadmapi.InitConfiguration, client clientset.Interface) error {
|
func EnsureProxyAddon(cfg *kubeadmapi.InitConfiguration, client clientset.Interface) error {
|
||||||
if err := CreateServiceAccount(client); err != nil {
|
if err := CreateServiceAccount(client); err != nil {
|
||||||
return fmt.Errorf("error when creating kube-proxy service account: %v", err)
|
return errors.Wrap(err, "error when creating kube-proxy service account")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate Master Enpoint kubeconfig file
|
// Generate Master Enpoint kubeconfig file
|
||||||
@@ -59,7 +61,7 @@ func EnsureProxyAddon(cfg *kubeadmapi.InitConfiguration, client clientset.Interf
|
|||||||
|
|
||||||
proxyBytes, err := componentconfigs.Known[componentconfigs.KubeProxyConfigurationKind].Marshal(cfg.ComponentConfigs.KubeProxy)
|
proxyBytes, err := componentconfigs.Known[componentconfigs.KubeProxyConfigurationKind].Marshal(cfg.ComponentConfigs.KubeProxy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error when marshaling: %v", err)
|
return errors.Wrap(err, "error when marshaling")
|
||||||
}
|
}
|
||||||
var prefixBytes bytes.Buffer
|
var prefixBytes bytes.Buffer
|
||||||
apiclient.PrintBytesWithLinePrefix(&prefixBytes, proxyBytes, " ")
|
apiclient.PrintBytesWithLinePrefix(&prefixBytes, proxyBytes, " ")
|
||||||
@@ -77,7 +79,7 @@ func EnsureProxyAddon(cfg *kubeadmapi.InitConfiguration, client clientset.Interf
|
|||||||
ProxyConfigMapKey: constants.KubeProxyConfigMapKey,
|
ProxyConfigMapKey: constants.KubeProxyConfigMapKey,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error when parsing kube-proxy configmap template: %v", err)
|
return errors.Wrap(err, "error when parsing kube-proxy configmap template")
|
||||||
}
|
}
|
||||||
proxyDaemonSetBytes, err = kubeadmutil.ParseTemplate(KubeProxyDaemonSet19, struct{ Image, ProxyConfigMap, ProxyConfigMapKey string }{
|
proxyDaemonSetBytes, err = kubeadmutil.ParseTemplate(KubeProxyDaemonSet19, struct{ Image, ProxyConfigMap, ProxyConfigMapKey string }{
|
||||||
Image: images.GetKubeControlPlaneImage(constants.KubeProxy, &cfg.ClusterConfiguration),
|
Image: images.GetKubeControlPlaneImage(constants.KubeProxy, &cfg.ClusterConfiguration),
|
||||||
@@ -85,13 +87,13 @@ func EnsureProxyAddon(cfg *kubeadmapi.InitConfiguration, client clientset.Interf
|
|||||||
ProxyConfigMapKey: constants.KubeProxyConfigMapKey,
|
ProxyConfigMapKey: constants.KubeProxyConfigMapKey,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error when parsing kube-proxy daemonset template: %v", err)
|
return errors.Wrap(err, "error when parsing kube-proxy daemonset template")
|
||||||
}
|
}
|
||||||
if err := createKubeProxyAddon(proxyConfigMapBytes, proxyDaemonSetBytes, client); err != nil {
|
if err := createKubeProxyAddon(proxyConfigMapBytes, proxyDaemonSetBytes, client); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := CreateRBACRules(client); err != nil {
|
if err := CreateRBACRules(client); err != nil {
|
||||||
return fmt.Errorf("error when creating kube-proxy RBAC rules: %v", err)
|
return errors.Wrap(err, "error when creating kube-proxy RBAC rules")
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("[addons] Applied essential addon: kube-proxy")
|
fmt.Println("[addons] Applied essential addon: kube-proxy")
|
||||||
@@ -117,7 +119,7 @@ func CreateRBACRules(client clientset.Interface) error {
|
|||||||
func createKubeProxyAddon(configMapBytes, daemonSetbytes []byte, client clientset.Interface) error {
|
func createKubeProxyAddon(configMapBytes, daemonSetbytes []byte, client clientset.Interface) error {
|
||||||
kubeproxyConfigMap := &v1.ConfigMap{}
|
kubeproxyConfigMap := &v1.ConfigMap{}
|
||||||
if err := kuberuntime.DecodeInto(clientsetscheme.Codecs.UniversalDecoder(), configMapBytes, kubeproxyConfigMap); err != nil {
|
if err := kuberuntime.DecodeInto(clientsetscheme.Codecs.UniversalDecoder(), configMapBytes, kubeproxyConfigMap); err != nil {
|
||||||
return fmt.Errorf("unable to decode kube-proxy configmap %v", err)
|
return errors.Wrap(err, "unable to decode kube-proxy configmap")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the ConfigMap for kube-proxy or update it in case it already exists
|
// Create the ConfigMap for kube-proxy or update it in case it already exists
|
||||||
@@ -127,7 +129,7 @@ func createKubeProxyAddon(configMapBytes, daemonSetbytes []byte, client clientse
|
|||||||
|
|
||||||
kubeproxyDaemonSet := &apps.DaemonSet{}
|
kubeproxyDaemonSet := &apps.DaemonSet{}
|
||||||
if err := kuberuntime.DecodeInto(clientsetscheme.Codecs.UniversalDecoder(), daemonSetbytes, kubeproxyDaemonSet); err != nil {
|
if err := kuberuntime.DecodeInto(clientsetscheme.Codecs.UniversalDecoder(), daemonSetbytes, kubeproxyDaemonSet); err != nil {
|
||||||
return fmt.Errorf("unable to decode kube-proxy daemonset %v", err)
|
return errors.Wrap(err, "unable to decode kube-proxy daemonset")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the DaemonSet for kube-proxy or update it in case it already exists
|
// Create the DaemonSet for kube-proxy or update it in case it already exists
|
||||||
|
@@ -20,6 +20,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
rbac "k8s.io/api/rbac/v1"
|
rbac "k8s.io/api/rbac/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
@@ -45,7 +47,7 @@ func CreateBootstrapConfigMapIfNotExists(client clientset.Interface, file string
|
|||||||
glog.V(1).Infoln("[bootstraptoken] loading admin kubeconfig")
|
glog.V(1).Infoln("[bootstraptoken] loading admin kubeconfig")
|
||||||
adminConfig, err := clientcmd.LoadFromFile(file)
|
adminConfig, err := clientcmd.LoadFromFile(file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to load admin kubeconfig [%v]", err)
|
return errors.Wrap(err, "failed to load admin kubeconfig")
|
||||||
}
|
}
|
||||||
|
|
||||||
adminCluster := adminConfig.Contexts[adminConfig.CurrentContext].Cluster
|
adminCluster := adminConfig.Contexts[adminConfig.CurrentContext].Cluster
|
||||||
|
@@ -17,7 +17,7 @@ limitations under the License.
|
|||||||
package node
|
package node
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
clientset "k8s.io/client-go/kubernetes"
|
clientset "k8s.io/client-go/kubernetes"
|
||||||
@@ -41,14 +41,14 @@ func UpdateOrCreateTokens(client clientset.Interface, failIfExists bool, tokens
|
|||||||
secretName := bootstraputil.BootstrapTokenSecretName(token.Token.ID)
|
secretName := bootstraputil.BootstrapTokenSecretName(token.Token.ID)
|
||||||
secret, err := client.CoreV1().Secrets(metav1.NamespaceSystem).Get(secretName, metav1.GetOptions{})
|
secret, err := client.CoreV1().Secrets(metav1.NamespaceSystem).Get(secretName, metav1.GetOptions{})
|
||||||
if secret != nil && err == nil && failIfExists {
|
if secret != nil && err == nil && failIfExists {
|
||||||
return fmt.Errorf("a token with id %q already exists", token.Token.ID)
|
return errors.Errorf("a token with id %q already exists", token.Token.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
updatedOrNewSecret := token.ToSecret()
|
updatedOrNewSecret := token.ToSecret()
|
||||||
// Try to create or update the token with an exponential backoff
|
// Try to create or update the token with an exponential backoff
|
||||||
err = apiclient.TryRunCommand(func() error {
|
err = apiclient.TryRunCommand(func() error {
|
||||||
if err := apiclient.CreateOrUpdateSecret(client, updatedOrNewSecret); err != nil {
|
if err := apiclient.CreateOrUpdateSecret(client, updatedOrNewSecret); err != nil {
|
||||||
return fmt.Errorf("failed to create or update bootstrap token with name %s: %v", secretName, err)
|
return errors.Wrapf(err, "failed to create or update bootstrap token with name %s", secretName)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}, 5)
|
}, 5)
|
||||||
|
@@ -19,7 +19,8 @@ package certs
|
|||||||
import (
|
import (
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"fmt"
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
certutil "k8s.io/client-go/util/cert"
|
certutil "k8s.io/client-go/util/cert"
|
||||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
@@ -56,7 +57,7 @@ func (k *KubeadmCert) GetConfig(ic *kubeadmapi.InitConfiguration) (*certutil.Con
|
|||||||
func (k *KubeadmCert) CreateFromCA(ic *kubeadmapi.InitConfiguration, caCert *x509.Certificate, caKey *rsa.PrivateKey) error {
|
func (k *KubeadmCert) CreateFromCA(ic *kubeadmapi.InitConfiguration, caCert *x509.Certificate, caKey *rsa.PrivateKey) error {
|
||||||
cfg, err := k.GetConfig(ic)
|
cfg, err := k.GetConfig(ic)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("couldn't create %q certificate: %v", k.Name, err)
|
return errors.Wrapf(err, "couldn't create %q certificate", k.Name)
|
||||||
}
|
}
|
||||||
cert, key, err := pkiutil.NewCertAndKey(caCert, caKey, cfg)
|
cert, key, err := pkiutil.NewCertAndKey(caCert, caKey, cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -71,7 +72,7 @@ func (k *KubeadmCert) CreateFromCA(ic *kubeadmapi.InitConfiguration, caCert *x50
|
|||||||
)
|
)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to write certificate %q: %v", k.Name, err)
|
return errors.Wrapf(err, "failed to write certificate %q", k.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -81,11 +82,11 @@ func (k *KubeadmCert) CreateFromCA(ic *kubeadmapi.InitConfiguration, caCert *x50
|
|||||||
func (k *KubeadmCert) CreateAsCA(ic *kubeadmapi.InitConfiguration) (*x509.Certificate, *rsa.PrivateKey, error) {
|
func (k *KubeadmCert) CreateAsCA(ic *kubeadmapi.InitConfiguration) (*x509.Certificate, *rsa.PrivateKey, error) {
|
||||||
cfg, err := k.GetConfig(ic)
|
cfg, err := k.GetConfig(ic)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("couldn't get configuration for %q CA certificate: %v", k.Name, err)
|
return nil, nil, errors.Wrapf(err, "couldn't get configuration for %q CA certificate", k.Name)
|
||||||
}
|
}
|
||||||
caCert, caKey, err := NewCACertAndKey(cfg)
|
caCert, caKey, err := NewCACertAndKey(cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("couldn't generate %q CA certificate: %v", k.Name, err)
|
return nil, nil, errors.Wrapf(err, "couldn't generate %q CA certificate", k.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = writeCertificateAuthorithyFilesIfNotExist(
|
err = writeCertificateAuthorithyFilesIfNotExist(
|
||||||
@@ -95,7 +96,7 @@ func (k *KubeadmCert) CreateAsCA(ic *kubeadmapi.InitConfiguration) (*x509.Certif
|
|||||||
caKey,
|
caKey,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("couldn't write out %q CA certificate: %v", k.Name, err)
|
return nil, nil, errors.Wrapf(err, "couldn't write out %q CA certificate", k.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
return caCert, caKey, nil
|
return caCert, caKey, nil
|
||||||
@@ -118,7 +119,7 @@ func (t CertificateTree) CreateTree(ic *kubeadmapi.InitConfiguration) error {
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
// Cert exists already, make sure it's valid
|
// Cert exists already, make sure it's valid
|
||||||
if !caCert.IsCA {
|
if !caCert.IsCA {
|
||||||
return fmt.Errorf("certificate %q is not a CA", ca.Name)
|
return errors.Errorf("certificate %q is not a CA", ca.Name)
|
||||||
}
|
}
|
||||||
// Try and load a CA Key
|
// Try and load a CA Key
|
||||||
caKey, err = pkiutil.TryLoadKeyFromDisk(ic.CertificatesDir, ca.BaseName)
|
caKey, err = pkiutil.TryLoadKeyFromDisk(ic.CertificatesDir, ca.BaseName)
|
||||||
@@ -131,10 +132,9 @@ func (t CertificateTree) CreateTree(ic *kubeadmapi.InitConfiguration) error {
|
|||||||
uxName: leaf.Name,
|
uxName: leaf.Name,
|
||||||
}
|
}
|
||||||
if err := validateSignedCertWithCA(cl, caCert); err != nil {
|
if err := validateSignedCertWithCA(cl, caCert); err != nil {
|
||||||
return fmt.Errorf("could not load expected certificate %q or validate the existence of key %q for it: %v", leaf.Name, ca.Name, err)
|
return errors.Wrapf(err, "could not load expected certificate %q or validate the existence of key %q for it", leaf.Name, ca.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// CACert exists and all clients exist, continue to next CA.
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// CA key exists; just use that to create new certificates.
|
// CA key exists; just use that to create new certificates.
|
||||||
@@ -180,7 +180,7 @@ func (m CertificateMap) CertTree() (CertificateTree, error) {
|
|||||||
} else {
|
} else {
|
||||||
ca, ok := m[cert.CAName]
|
ca, ok := m[cert.CAName]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("Certificate %q references unknown CA %q", cert.Name, cert.CAName)
|
return nil, errors.Errorf("certificate %q references unknown CA %q", cert.Name, cert.CAName)
|
||||||
}
|
}
|
||||||
caMap[ca] = append(caMap[ca], cert)
|
caMap[ca] = append(caMap[ca], cert)
|
||||||
}
|
}
|
||||||
|
@@ -24,6 +24,8 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
certutil "k8s.io/client-go/util/cert"
|
certutil "k8s.io/client-go/util/cert"
|
||||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||||
@@ -52,7 +54,7 @@ func CreatePKIAssets(cfg *kubeadmapi.InitConfiguration) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err := certTree.CreateTree(cfg); err != nil {
|
if err := certTree.CreateTree(cfg); err != nil {
|
||||||
return fmt.Errorf("Error creating PKI assets: %v", err)
|
return errors.Wrap(err, "error creating PKI assets")
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("[certificates] valid certificates and keys now exist in %q\n", cfg.CertificatesDir)
|
fmt.Printf("[certificates] valid certificates and keys now exist in %q\n", cfg.CertificatesDir)
|
||||||
@@ -86,7 +88,7 @@ func NewServiceAccountSigningKey() (*rsa.PrivateKey, error) {
|
|||||||
// The key does NOT exist, let's generate it now
|
// The key does NOT exist, let's generate it now
|
||||||
saSigningKey, err := certutil.NewPrivateKey()
|
saSigningKey, err := certutil.NewPrivateKey()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failure while creating service account token signing key: %v", err)
|
return nil, errors.Wrap(err, "failure while creating service account token signing key")
|
||||||
}
|
}
|
||||||
|
|
||||||
return saSigningKey, nil
|
return saSigningKey, nil
|
||||||
@@ -97,7 +99,7 @@ func NewCACertAndKey(certSpec *certutil.Config) (*x509.Certificate, *rsa.Private
|
|||||||
|
|
||||||
caCert, caKey, err := pkiutil.NewCertificateAuthority(certSpec)
|
caCert, caKey, err := pkiutil.NewCertificateAuthority(certSpec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("failure while generating CA certificate and key: %v", err)
|
return nil, nil, errors.Wrap(err, "failure while generating CA certificate and key")
|
||||||
}
|
}
|
||||||
|
|
||||||
return caCert, caKey, nil
|
return caCert, caKey, nil
|
||||||
@@ -107,7 +109,7 @@ func NewCACertAndKey(certSpec *certutil.Config) (*x509.Certificate, *rsa.Private
|
|||||||
// The certSpec should be one of the variables from this package.
|
// The certSpec should be one of the variables from this package.
|
||||||
func CreateCACertAndKeyFiles(certSpec *KubeadmCert, cfg *kubeadmapi.InitConfiguration) error {
|
func CreateCACertAndKeyFiles(certSpec *KubeadmCert, cfg *kubeadmapi.InitConfiguration) error {
|
||||||
if certSpec.CAName != "" {
|
if certSpec.CAName != "" {
|
||||||
return fmt.Errorf("This function should only be used for CAs, but cert %s has CA %s", certSpec.Name, certSpec.CAName)
|
return errors.Errorf("this function should only be used for CAs, but cert %s has CA %s", certSpec.Name, certSpec.CAName)
|
||||||
}
|
}
|
||||||
glog.V(1).Infof("creating a new certificate authority for %s", certSpec.Name)
|
glog.V(1).Infof("creating a new certificate authority for %s", certSpec.Name)
|
||||||
|
|
||||||
@@ -133,12 +135,12 @@ func CreateCACertAndKeyFiles(certSpec *KubeadmCert, cfg *kubeadmapi.InitConfigur
|
|||||||
// The certSpec and caCertSpec should both be one of the variables from this package.
|
// The certSpec and caCertSpec should both be one of the variables from this package.
|
||||||
func CreateCertAndKeyFilesWithCA(certSpec *KubeadmCert, caCertSpec *KubeadmCert, cfg *kubeadmapi.InitConfiguration) error {
|
func CreateCertAndKeyFilesWithCA(certSpec *KubeadmCert, caCertSpec *KubeadmCert, cfg *kubeadmapi.InitConfiguration) error {
|
||||||
if certSpec.CAName != caCertSpec.Name {
|
if certSpec.CAName != caCertSpec.Name {
|
||||||
return fmt.Errorf("Expected CAname for %s to be %q, but was %s", certSpec.Name, certSpec.CAName, caCertSpec.Name)
|
return errors.Errorf("expected CAname for %s to be %q, but was %s", certSpec.Name, certSpec.CAName, caCertSpec.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
caCert, caKey, err := LoadCertificateAuthority(cfg.CertificatesDir, caCertSpec.BaseName)
|
caCert, caKey, err := LoadCertificateAuthority(cfg.CertificatesDir, caCertSpec.BaseName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Couldn't load CA certificate %s: %v", caCertSpec.Name, err)
|
return errors.Wrapf(err, "couldn't load CA certificate %s", caCertSpec.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
return certSpec.CreateFromCA(cfg, caCert, caKey)
|
return certSpec.CreateFromCA(cfg, caCert, caKey)
|
||||||
@@ -148,18 +150,18 @@ func CreateCertAndKeyFilesWithCA(certSpec *KubeadmCert, caCertSpec *KubeadmCert,
|
|||||||
func LoadCertificateAuthority(pkiDir string, baseName string) (*x509.Certificate, *rsa.PrivateKey, error) {
|
func LoadCertificateAuthority(pkiDir string, baseName string) (*x509.Certificate, *rsa.PrivateKey, error) {
|
||||||
// Checks if certificate authority exists in the PKI directory
|
// Checks if certificate authority exists in the PKI directory
|
||||||
if !pkiutil.CertOrKeyExist(pkiDir, baseName) {
|
if !pkiutil.CertOrKeyExist(pkiDir, baseName) {
|
||||||
return nil, nil, fmt.Errorf("couldn't load %s certificate authority from %s", baseName, pkiDir)
|
return nil, nil, errors.Errorf("couldn't load %s certificate authority from %s", baseName, pkiDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to load certificate authority .crt and .key from the PKI directory
|
// Try to load certificate authority .crt and .key from the PKI directory
|
||||||
caCert, caKey, err := pkiutil.TryLoadCertAndKeyFromDisk(pkiDir, baseName)
|
caCert, caKey, err := pkiutil.TryLoadCertAndKeyFromDisk(pkiDir, baseName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("failure loading %s certificate authority: %v", baseName, err)
|
return nil, nil, errors.Wrapf(err, "failure loading %s certificate authority", baseName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure the loaded CA cert actually is a CA
|
// Make sure the loaded CA cert actually is a CA
|
||||||
if !caCert.IsCA {
|
if !caCert.IsCA {
|
||||||
return nil, nil, fmt.Errorf("%s certificate is not a certificate authority", baseName)
|
return nil, nil, errors.Errorf("%s certificate is not a certificate authority", baseName)
|
||||||
}
|
}
|
||||||
|
|
||||||
return caCert, caKey, nil
|
return caCert, caKey, nil
|
||||||
@@ -177,12 +179,12 @@ func writeCertificateAuthorithyFilesIfNotExist(pkiDir string, baseName string, c
|
|||||||
// Try to load .crt and .key from the PKI directory
|
// Try to load .crt and .key from the PKI directory
|
||||||
caCert, _, err := pkiutil.TryLoadCertAndKeyFromDisk(pkiDir, baseName)
|
caCert, _, err := pkiutil.TryLoadCertAndKeyFromDisk(pkiDir, baseName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failure loading %s certificate: %v", baseName, err)
|
return errors.Wrapf(err, "failure loading %s certificate", baseName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the existing cert is a CA
|
// Check if the existing cert is a CA
|
||||||
if !caCert.IsCA {
|
if !caCert.IsCA {
|
||||||
return fmt.Errorf("certificate %s is not a CA", baseName)
|
return errors.Errorf("certificate %s is not a CA", baseName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// kubeadm doesn't validate the existing certificate Authority more than this;
|
// kubeadm doesn't validate the existing certificate Authority more than this;
|
||||||
@@ -193,7 +195,7 @@ func writeCertificateAuthorithyFilesIfNotExist(pkiDir string, baseName string, c
|
|||||||
|
|
||||||
// Write .crt and .key files to disk
|
// Write .crt and .key files to disk
|
||||||
if err := pkiutil.WriteCertAndKey(pkiDir, baseName, caCert, caKey); err != nil {
|
if err := pkiutil.WriteCertAndKey(pkiDir, baseName, caCert, caKey); err != nil {
|
||||||
return fmt.Errorf("failure while saving %s certificate and key: %v", baseName, err)
|
return errors.Wrapf(err, "failure while saving %s certificate and key", baseName)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("[certificates] Generated %s certificate and key.\n", baseName)
|
fmt.Printf("[certificates] Generated %s certificate and key.\n", baseName)
|
||||||
@@ -212,12 +214,12 @@ func writeCertificateFilesIfNotExist(pkiDir string, baseName string, signingCert
|
|||||||
// Try to load signed certificate .crt and .key from the PKI directory
|
// Try to load signed certificate .crt and .key from the PKI directory
|
||||||
signedCert, _, err := pkiutil.TryLoadCertAndKeyFromDisk(pkiDir, baseName)
|
signedCert, _, err := pkiutil.TryLoadCertAndKeyFromDisk(pkiDir, baseName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failure loading %s certificate: %v", baseName, err)
|
return errors.Wrapf(err, "failure loading %s certificate", baseName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the existing cert is signed by the given CA
|
// Check if the existing cert is signed by the given CA
|
||||||
if err := signedCert.CheckSignatureFrom(signingCert); err != nil {
|
if err := signedCert.CheckSignatureFrom(signingCert); err != nil {
|
||||||
return fmt.Errorf("certificate %s is not signed by corresponding CA", baseName)
|
return errors.Errorf("certificate %s is not signed by corresponding CA", baseName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// kubeadm doesn't validate the existing certificate more than this;
|
// kubeadm doesn't validate the existing certificate more than this;
|
||||||
@@ -229,7 +231,7 @@ func writeCertificateFilesIfNotExist(pkiDir string, baseName string, signingCert
|
|||||||
|
|
||||||
// Write .crt and .key files to disk
|
// Write .crt and .key files to disk
|
||||||
if err := pkiutil.WriteCertAndKey(pkiDir, baseName, cert, key); err != nil {
|
if err := pkiutil.WriteCertAndKey(pkiDir, baseName, cert, key); err != nil {
|
||||||
return fmt.Errorf("failure while saving %s certificate and key: %v", baseName, err)
|
return errors.Wrapf(err, "failure while saving %s certificate and key", baseName)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("[certificates] Generated %s certificate and key.\n", baseName)
|
fmt.Printf("[certificates] Generated %s certificate and key.\n", baseName)
|
||||||
@@ -253,7 +255,7 @@ func writeKeyFilesIfNotExist(pkiDir string, baseName string, key *rsa.PrivateKey
|
|||||||
// Try to load .key from the PKI directory
|
// Try to load .key from the PKI directory
|
||||||
_, err := pkiutil.TryLoadKeyFromDisk(pkiDir, baseName)
|
_, err := pkiutil.TryLoadKeyFromDisk(pkiDir, baseName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("%s key existed but it could not be loaded properly: %v", baseName, err)
|
return errors.Wrapf(err, "%s key existed but it could not be loaded properly", baseName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// kubeadm doesn't validate the existing certificate key more than this;
|
// kubeadm doesn't validate the existing certificate key more than this;
|
||||||
@@ -264,11 +266,11 @@ func writeKeyFilesIfNotExist(pkiDir string, baseName string, key *rsa.PrivateKey
|
|||||||
|
|
||||||
// Write .key and .pub files to disk
|
// Write .key and .pub files to disk
|
||||||
if err := pkiutil.WriteKey(pkiDir, baseName, key); err != nil {
|
if err := pkiutil.WriteKey(pkiDir, baseName, key); err != nil {
|
||||||
return fmt.Errorf("failure while saving %s key: %v", baseName, err)
|
return errors.Wrapf(err, "failure while saving %s key", baseName)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := pkiutil.WritePublicKey(pkiDir, baseName, &key.PublicKey); err != nil {
|
if err := pkiutil.WritePublicKey(pkiDir, baseName, &key.PublicKey); err != nil {
|
||||||
return fmt.Errorf("failure while saving %s public key: %v", baseName, err)
|
return errors.Wrapf(err, "failure while saving %s public key", baseName)
|
||||||
}
|
}
|
||||||
fmt.Printf("[certificates] Generated %s key and public key.\n", baseName)
|
fmt.Printf("[certificates] Generated %s key and public key.\n", baseName)
|
||||||
}
|
}
|
||||||
@@ -320,7 +322,7 @@ func UsingExternalCA(cfg *kubeadmapi.InitConfiguration) (bool, error) {
|
|||||||
|
|
||||||
caKeyPath := filepath.Join(cfg.CertificatesDir, kubeadmconstants.CAKeyName)
|
caKeyPath := filepath.Join(cfg.CertificatesDir, kubeadmconstants.CAKeyName)
|
||||||
if _, err := os.Stat(caKeyPath); !os.IsNotExist(err) {
|
if _, err := os.Stat(caKeyPath); !os.IsNotExist(err) {
|
||||||
return false, fmt.Errorf("%s exists", kubeadmconstants.CAKeyName)
|
return false, errors.Errorf("%s exists", kubeadmconstants.CAKeyName)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := validateSignedCert(certKeyLocation{cfg.CertificatesDir, kubeadmconstants.CACertAndKeyBaseName, kubeadmconstants.APIServerCertAndKeyBaseName, "API server"}); err != nil {
|
if err := validateSignedCert(certKeyLocation{cfg.CertificatesDir, kubeadmconstants.CACertAndKeyBaseName, kubeadmconstants.APIServerCertAndKeyBaseName, "API server"}); err != nil {
|
||||||
@@ -341,7 +343,7 @@ func UsingExternalCA(cfg *kubeadmapi.InitConfiguration) (bool, error) {
|
|||||||
|
|
||||||
frontProxyCAKeyPath := filepath.Join(cfg.CertificatesDir, kubeadmconstants.FrontProxyCAKeyName)
|
frontProxyCAKeyPath := filepath.Join(cfg.CertificatesDir, kubeadmconstants.FrontProxyCAKeyName)
|
||||||
if _, err := os.Stat(frontProxyCAKeyPath); !os.IsNotExist(err) {
|
if _, err := os.Stat(frontProxyCAKeyPath); !os.IsNotExist(err) {
|
||||||
return false, fmt.Errorf("%s exists", kubeadmconstants.FrontProxyCAKeyName)
|
return false, errors.Errorf("%s exists", kubeadmconstants.FrontProxyCAKeyName)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := validateSignedCert(certKeyLocation{cfg.CertificatesDir, kubeadmconstants.FrontProxyCACertAndKeyBaseName, kubeadmconstants.FrontProxyClientCertAndKeyBaseName, "front-proxy client"}); err != nil {
|
if err := validateSignedCert(certKeyLocation{cfg.CertificatesDir, kubeadmconstants.FrontProxyCACertAndKeyBaseName, kubeadmconstants.FrontProxyClientCertAndKeyBaseName, "front-proxy client"}); err != nil {
|
||||||
@@ -356,12 +358,12 @@ func validateCACert(l certKeyLocation) error {
|
|||||||
// Check CA Cert
|
// Check CA Cert
|
||||||
caCert, err := pkiutil.TryLoadCertFromDisk(l.pkiDir, l.caBaseName)
|
caCert, err := pkiutil.TryLoadCertFromDisk(l.pkiDir, l.caBaseName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failure loading certificate for %s: %v", l.uxName, err)
|
return errors.Wrapf(err, "failure loading certificate for %s", l.uxName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if cert is a CA
|
// Check if cert is a CA
|
||||||
if !caCert.IsCA {
|
if !caCert.IsCA {
|
||||||
return fmt.Errorf("certificate %s is not a CA", l.uxName)
|
return errors.Errorf("certificate %s is not a CA", l.uxName)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -375,7 +377,7 @@ func validateCACertAndKey(l certKeyLocation) error {
|
|||||||
|
|
||||||
_, err := pkiutil.TryLoadKeyFromDisk(l.pkiDir, l.caBaseName)
|
_, err := pkiutil.TryLoadKeyFromDisk(l.pkiDir, l.caBaseName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failure loading key for %s: %v", l.uxName, err)
|
return errors.Wrapf(err, "failure loading key for %s", l.uxName)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -386,7 +388,7 @@ func validateSignedCert(l certKeyLocation) error {
|
|||||||
// Try to load CA
|
// Try to load CA
|
||||||
caCert, err := pkiutil.TryLoadCertFromDisk(l.pkiDir, l.caBaseName)
|
caCert, err := pkiutil.TryLoadCertFromDisk(l.pkiDir, l.caBaseName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failure loading certificate authority for %s: %v", l.uxName, err)
|
return errors.Wrapf(err, "failure loading certificate authority for %s", l.uxName)
|
||||||
}
|
}
|
||||||
|
|
||||||
return validateSignedCertWithCA(l, caCert)
|
return validateSignedCertWithCA(l, caCert)
|
||||||
@@ -397,12 +399,12 @@ func validateSignedCertWithCA(l certKeyLocation, caCert *x509.Certificate) error
|
|||||||
// Try to load key and signed certificate
|
// Try to load key and signed certificate
|
||||||
signedCert, _, err := pkiutil.TryLoadCertAndKeyFromDisk(l.pkiDir, l.baseName)
|
signedCert, _, err := pkiutil.TryLoadCertAndKeyFromDisk(l.pkiDir, l.baseName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failure loading certificate for %s: %v", l.uxName, err)
|
return errors.Wrapf(err, "failure loading certificate for %s", l.uxName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the cert is signed by the CA
|
// Check if the cert is signed by the CA
|
||||||
if err := signedCert.CheckSignatureFrom(caCert); err != nil {
|
if err := signedCert.CheckSignatureFrom(caCert); err != nil {
|
||||||
return fmt.Errorf("certificate %s is not signed by corresponding CA", l.uxName)
|
return errors.Wrapf(err, "certificate %s is not signed by corresponding CA", l.uxName)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -412,7 +414,7 @@ func validatePrivatePublicKey(l certKeyLocation) error {
|
|||||||
// Try to load key
|
// Try to load key
|
||||||
_, _, err := pkiutil.TryLoadPrivatePublicKeyFromDisk(l.pkiDir, l.baseName)
|
_, _, err := pkiutil.TryLoadPrivatePublicKeyFromDisk(l.pkiDir, l.baseName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failure loading key for %s: %v", l.uxName, err)
|
return errors.Wrapf(err, "failure loading key for %s", l.uxName)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@@ -19,12 +19,13 @@ package certs
|
|||||||
import (
|
import (
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
certutil "k8s.io/client-go/util/cert"
|
certutil "k8s.io/client-go/util/cert"
|
||||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||||
@@ -704,14 +705,14 @@ func TestCreateCertificateFilesMethods(t *testing.T) {
|
|||||||
|
|
||||||
func deleteCAKey(cfg *kubeadmapi.InitConfiguration) error {
|
func deleteCAKey(cfg *kubeadmapi.InitConfiguration) error {
|
||||||
if err := os.Remove(filepath.Join(cfg.CertificatesDir, kubeadmconstants.CAKeyName)); err != nil {
|
if err := os.Remove(filepath.Join(cfg.CertificatesDir, kubeadmconstants.CAKeyName)); err != nil {
|
||||||
return fmt.Errorf("failed removing %s: %v", kubeadmconstants.CAKeyName, err)
|
return errors.Wrapf(err, "failed removing %s", kubeadmconstants.CAKeyName)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteFrontProxyCAKey(cfg *kubeadmapi.InitConfiguration) error {
|
func deleteFrontProxyCAKey(cfg *kubeadmapi.InitConfiguration) error {
|
||||||
if err := os.Remove(filepath.Join(cfg.CertificatesDir, kubeadmconstants.FrontProxyCAKeyName)); err != nil {
|
if err := os.Remove(filepath.Join(cfg.CertificatesDir, kubeadmconstants.FrontProxyCAKeyName)); err != nil {
|
||||||
return fmt.Errorf("failed removing %s: %v", kubeadmconstants.FrontProxyCAKeyName, err)
|
return errors.Wrapf(err, "failed removing %s", kubeadmconstants.FrontProxyCAKeyName)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@@ -26,6 +26,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/util/validation"
|
"k8s.io/apimachinery/pkg/util/validation"
|
||||||
certutil "k8s.io/client-go/util/cert"
|
certutil "k8s.io/client-go/util/cert"
|
||||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
@@ -38,12 +39,12 @@ import (
|
|||||||
func NewCertificateAuthority(config *certutil.Config) (*x509.Certificate, *rsa.PrivateKey, error) {
|
func NewCertificateAuthority(config *certutil.Config) (*x509.Certificate, *rsa.PrivateKey, error) {
|
||||||
key, err := certutil.NewPrivateKey()
|
key, err := certutil.NewPrivateKey()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("unable to create private key [%v]", err)
|
return nil, nil, errors.Wrap(err, "unable to create private key")
|
||||||
}
|
}
|
||||||
|
|
||||||
cert, err := certutil.NewSelfSignedCACert(*config, key)
|
cert, err := certutil.NewSelfSignedCACert(*config, key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("unable to create self-signed certificate [%v]", err)
|
return nil, nil, errors.Wrap(err, "unable to create self-signed certificate")
|
||||||
}
|
}
|
||||||
|
|
||||||
return cert, key, nil
|
return cert, key, nil
|
||||||
@@ -53,12 +54,12 @@ func NewCertificateAuthority(config *certutil.Config) (*x509.Certificate, *rsa.P
|
|||||||
func NewCertAndKey(caCert *x509.Certificate, caKey *rsa.PrivateKey, config *certutil.Config) (*x509.Certificate, *rsa.PrivateKey, error) {
|
func NewCertAndKey(caCert *x509.Certificate, caKey *rsa.PrivateKey, config *certutil.Config) (*x509.Certificate, *rsa.PrivateKey, error) {
|
||||||
key, err := certutil.NewPrivateKey()
|
key, err := certutil.NewPrivateKey()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("unable to create private key [%v]", err)
|
return nil, nil, errors.Wrap(err, "unable to create private key")
|
||||||
}
|
}
|
||||||
|
|
||||||
cert, err := certutil.NewSignedCert(*config, key, caCert, caKey)
|
cert, err := certutil.NewSignedCert(*config, key, caCert, caKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("unable to sign certificate [%v]", err)
|
return nil, nil, errors.Wrap(err, "unable to sign certificate")
|
||||||
}
|
}
|
||||||
|
|
||||||
return cert, key, nil
|
return cert, key, nil
|
||||||
@@ -86,12 +87,12 @@ func WriteCertAndKey(pkiPath string, name string, cert *x509.Certificate, key *r
|
|||||||
// WriteCert stores the given certificate at the given location
|
// WriteCert stores the given certificate at the given location
|
||||||
func WriteCert(pkiPath, name string, cert *x509.Certificate) error {
|
func WriteCert(pkiPath, name string, cert *x509.Certificate) error {
|
||||||
if cert == nil {
|
if cert == nil {
|
||||||
return fmt.Errorf("certificate cannot be nil when writing to file")
|
return errors.New("certificate cannot be nil when writing to file")
|
||||||
}
|
}
|
||||||
|
|
||||||
certificatePath := pathForCert(pkiPath, name)
|
certificatePath := pathForCert(pkiPath, name)
|
||||||
if err := certutil.WriteCert(certificatePath, certutil.EncodeCertPEM(cert)); err != nil {
|
if err := certutil.WriteCert(certificatePath, certutil.EncodeCertPEM(cert)); err != nil {
|
||||||
return fmt.Errorf("unable to write certificate to file %q: [%v]", certificatePath, err)
|
return errors.Wrapf(err, "unable to write certificate to file %s", certificatePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -100,12 +101,12 @@ func WriteCert(pkiPath, name string, cert *x509.Certificate) error {
|
|||||||
// WriteKey stores the given key at the given location
|
// WriteKey stores the given key at the given location
|
||||||
func WriteKey(pkiPath, name string, key *rsa.PrivateKey) error {
|
func WriteKey(pkiPath, name string, key *rsa.PrivateKey) error {
|
||||||
if key == nil {
|
if key == nil {
|
||||||
return fmt.Errorf("private key cannot be nil when writing to file")
|
return errors.New("private key cannot be nil when writing to file")
|
||||||
}
|
}
|
||||||
|
|
||||||
privateKeyPath := pathForKey(pkiPath, name)
|
privateKeyPath := pathForKey(pkiPath, name)
|
||||||
if err := certutil.WriteKey(privateKeyPath, certutil.EncodePrivateKeyPEM(key)); err != nil {
|
if err := certutil.WriteKey(privateKeyPath, certutil.EncodePrivateKeyPEM(key)); err != nil {
|
||||||
return fmt.Errorf("unable to write private key to file %q: [%v]", privateKeyPath, err)
|
return errors.Wrapf(err, "unable to write private key to file %s", privateKeyPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -114,7 +115,7 @@ func WriteKey(pkiPath, name string, key *rsa.PrivateKey) error {
|
|||||||
// WritePublicKey stores the given public key at the given location
|
// WritePublicKey stores the given public key at the given location
|
||||||
func WritePublicKey(pkiPath, name string, key *rsa.PublicKey) error {
|
func WritePublicKey(pkiPath, name string, key *rsa.PublicKey) error {
|
||||||
if key == nil {
|
if key == nil {
|
||||||
return fmt.Errorf("public key cannot be nil when writing to file")
|
return errors.New("public key cannot be nil when writing to file")
|
||||||
}
|
}
|
||||||
|
|
||||||
publicKeyBytes, err := certutil.EncodePublicKeyPEM(key)
|
publicKeyBytes, err := certutil.EncodePublicKeyPEM(key)
|
||||||
@@ -123,7 +124,7 @@ func WritePublicKey(pkiPath, name string, key *rsa.PublicKey) error {
|
|||||||
}
|
}
|
||||||
publicKeyPath := pathForPublicKey(pkiPath, name)
|
publicKeyPath := pathForPublicKey(pkiPath, name)
|
||||||
if err := certutil.WriteKey(publicKeyPath, publicKeyBytes); err != nil {
|
if err := certutil.WriteKey(publicKeyPath, publicKeyBytes); err != nil {
|
||||||
return fmt.Errorf("unable to write public key to file %q: [%v]", publicKeyPath, err)
|
return errors.Wrapf(err, "unable to write public key to file %s", publicKeyPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -165,7 +166,7 @@ func TryLoadCertFromDisk(pkiPath, name string) (*x509.Certificate, error) {
|
|||||||
|
|
||||||
certs, err := certutil.CertsFromFile(certificatePath)
|
certs, err := certutil.CertsFromFile(certificatePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("couldn't load the certificate file %s: %v", certificatePath, err)
|
return nil, errors.Wrapf(err, "couldn't load the certificate file %s", certificatePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
// We are only putting one certificate in the certificate pem file, so it's safe to just pick the first one
|
// We are only putting one certificate in the certificate pem file, so it's safe to just pick the first one
|
||||||
@@ -175,10 +176,10 @@ func TryLoadCertFromDisk(pkiPath, name string) (*x509.Certificate, error) {
|
|||||||
// Check so that the certificate is valid now
|
// Check so that the certificate is valid now
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
if now.Before(cert.NotBefore) {
|
if now.Before(cert.NotBefore) {
|
||||||
return nil, fmt.Errorf("the certificate is not valid yet")
|
return nil, errors.New("the certificate is not valid yet")
|
||||||
}
|
}
|
||||||
if now.After(cert.NotAfter) {
|
if now.After(cert.NotAfter) {
|
||||||
return nil, fmt.Errorf("the certificate has expired")
|
return nil, errors.New("the certificate has expired")
|
||||||
}
|
}
|
||||||
|
|
||||||
return cert, nil
|
return cert, nil
|
||||||
@@ -191,7 +192,7 @@ func TryLoadKeyFromDisk(pkiPath, name string) (*rsa.PrivateKey, error) {
|
|||||||
// Parse the private key from a file
|
// Parse the private key from a file
|
||||||
privKey, err := certutil.PrivateKeyFromFile(privateKeyPath)
|
privKey, err := certutil.PrivateKeyFromFile(privateKeyPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("couldn't load the private key file %s: %v", privateKeyPath, err)
|
return nil, errors.Wrapf(err, "couldn't load the private key file %s", privateKeyPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow RSA format only
|
// Allow RSA format only
|
||||||
@@ -200,7 +201,7 @@ func TryLoadKeyFromDisk(pkiPath, name string) (*rsa.PrivateKey, error) {
|
|||||||
case *rsa.PrivateKey:
|
case *rsa.PrivateKey:
|
||||||
key = k
|
key = k
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("the private key file %s isn't in RSA format", privateKeyPath)
|
return nil, errors.Wrapf(err, "the private key file %s isn't in RSA format", privateKeyPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
return key, nil
|
return key, nil
|
||||||
@@ -213,7 +214,7 @@ func TryLoadPrivatePublicKeyFromDisk(pkiPath, name string) (*rsa.PrivateKey, *rs
|
|||||||
// Parse the private key from a file
|
// Parse the private key from a file
|
||||||
privKey, err := certutil.PrivateKeyFromFile(privateKeyPath)
|
privKey, err := certutil.PrivateKeyFromFile(privateKeyPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("couldn't load the private key file %s: %v", privateKeyPath, err)
|
return nil, nil, errors.Wrapf(err, "couldn't load the private key file %s", privateKeyPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
publicKeyPath := pathForPublicKey(pkiPath, name)
|
publicKeyPath := pathForPublicKey(pkiPath, name)
|
||||||
@@ -221,13 +222,13 @@ func TryLoadPrivatePublicKeyFromDisk(pkiPath, name string) (*rsa.PrivateKey, *rs
|
|||||||
// Parse the public key from a file
|
// Parse the public key from a file
|
||||||
pubKeys, err := certutil.PublicKeysFromFile(publicKeyPath)
|
pubKeys, err := certutil.PublicKeysFromFile(publicKeyPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("couldn't load the public key file %s: %v", publicKeyPath, err)
|
return nil, nil, errors.Wrapf(err, "couldn't load the public key file %s", publicKeyPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow RSA format only
|
// Allow RSA format only
|
||||||
k, ok := privKey.(*rsa.PrivateKey)
|
k, ok := privKey.(*rsa.PrivateKey)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, nil, fmt.Errorf("the private key file %s isn't in RSA format", privateKeyPath)
|
return nil, nil, errors.Wrapf(err, "the private key file %s isn't in RSA format", privateKeyPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
p := pubKeys[0].(*rsa.PublicKey)
|
p := pubKeys[0].(*rsa.PublicKey)
|
||||||
@@ -257,18 +258,19 @@ func GetAPIServerAltNames(cfg *kubeadmapi.InitConfiguration) (*certutil.AltNames
|
|||||||
// advertise address
|
// advertise address
|
||||||
advertiseAddress := net.ParseIP(cfg.APIEndpoint.AdvertiseAddress)
|
advertiseAddress := net.ParseIP(cfg.APIEndpoint.AdvertiseAddress)
|
||||||
if advertiseAddress == nil {
|
if advertiseAddress == nil {
|
||||||
return nil, fmt.Errorf("error parsing APIEndpoint AdvertiseAddress %v: is not a valid textual representation of an IP address", cfg.APIEndpoint.AdvertiseAddress)
|
return nil, errors.Errorf("error parsing APIEndpoint AdvertiseAddress %v: is not a valid textual representation of an IP address",
|
||||||
|
cfg.APIEndpoint.AdvertiseAddress)
|
||||||
}
|
}
|
||||||
|
|
||||||
// internal IP address for the API server
|
// internal IP address for the API server
|
||||||
_, svcSubnet, err := net.ParseCIDR(cfg.Networking.ServiceSubnet)
|
_, svcSubnet, err := net.ParseCIDR(cfg.Networking.ServiceSubnet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error parsing CIDR %q: %v", cfg.Networking.ServiceSubnet, err)
|
return nil, errors.Wrapf(err, "error parsing CIDR %q", cfg.Networking.ServiceSubnet)
|
||||||
}
|
}
|
||||||
|
|
||||||
internalAPIServerVirtualIP, err := ipallocator.GetIndexedIP(svcSubnet, 1)
|
internalAPIServerVirtualIP, err := ipallocator.GetIndexedIP(svcSubnet, 1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unable to get first IP address from the given CIDR (%s): %v", svcSubnet.String(), err)
|
return nil, errors.Wrapf(err, "unable to get first IP address from the given CIDR (%s)", svcSubnet.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
// create AltNames with defaults DNSNames/IPs
|
// create AltNames with defaults DNSNames/IPs
|
||||||
@@ -295,7 +297,7 @@ func GetAPIServerAltNames(cfg *kubeadmapi.InitConfiguration) (*certutil.AltNames
|
|||||||
altNames.DNSNames = append(altNames.DNSNames, host)
|
altNames.DNSNames = append(altNames.DNSNames, host)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return nil, fmt.Errorf("error parsing cluster controlPlaneEndpoint %q: %s", cfg.ControlPlaneEndpoint, err)
|
return nil, errors.Wrapf(err, "error parsing cluster controlPlaneEndpoint %q", cfg.ControlPlaneEndpoint)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -334,7 +336,8 @@ func GetEtcdPeerAltNames(cfg *kubeadmapi.InitConfiguration) (*certutil.AltNames,
|
|||||||
// advertise address
|
// advertise address
|
||||||
advertiseAddress := net.ParseIP(cfg.APIEndpoint.AdvertiseAddress)
|
advertiseAddress := net.ParseIP(cfg.APIEndpoint.AdvertiseAddress)
|
||||||
if advertiseAddress == nil {
|
if advertiseAddress == nil {
|
||||||
return nil, fmt.Errorf("error parsing APIEndpoint AdvertiseAddress %v: is not a valid textual representation of an IP address", cfg.APIEndpoint.AdvertiseAddress)
|
return nil, errors.Errorf("error parsing APIEndpoint AdvertiseAddress %v: is not a valid textual representation of an IP address",
|
||||||
|
cfg.APIEndpoint.AdvertiseAddress)
|
||||||
}
|
}
|
||||||
|
|
||||||
// create AltNames with defaults DNSNames/IPs
|
// create AltNames with defaults DNSNames/IPs
|
||||||
|
@@ -21,7 +21,6 @@ import (
|
|||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"crypto/x509/pkix"
|
"crypto/x509/pkix"
|
||||||
"fmt"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
@@ -80,7 +79,7 @@ func (r *CertsAPIRenewal) Renew(cfg *certutil.Config) (*x509.Certificate, *rsa.P
|
|||||||
for i, usage := range cfg.Usages {
|
for i, usage := range cfg.Usages {
|
||||||
certsAPIUsage, ok := usageMap[usage]
|
certsAPIUsage, ok := usageMap[usage]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, nil, fmt.Errorf("unknown key usage: %v", usage)
|
return nil, nil, errors.Errorf("unknown key usage: %v", usage)
|
||||||
}
|
}
|
||||||
usages[i] = certsAPIUsage
|
usages[i] = certsAPIUsage
|
||||||
}
|
}
|
||||||
@@ -112,7 +111,7 @@ func (r *CertsAPIRenewal) Renew(cfg *certutil.Config) (*x509.Certificate, *rsa.P
|
|||||||
select {
|
select {
|
||||||
case ev := <-watcher.ResultChan():
|
case ev := <-watcher.ResultChan():
|
||||||
if ev.Type != watch.Modified {
|
if ev.Type != watch.Modified {
|
||||||
return nil, nil, fmt.Errorf("unexpected event received: %q", ev.Type)
|
return nil, nil, errors.Errorf("unexpected event received: %q", ev.Type)
|
||||||
}
|
}
|
||||||
case <-time.After(watchTimeout):
|
case <-time.After(watchTimeout):
|
||||||
return nil, nil, errors.New("timeout trying to sign certificate")
|
return nil, nil, errors.New("timeout trying to sign certificate")
|
||||||
@@ -128,7 +127,7 @@ func (r *CertsAPIRenewal) Renew(cfg *certutil.Config) (*x509.Certificate, *rsa.P
|
|||||||
|
|
||||||
// TODO: under what circumstances are there more than one?
|
// TODO: under what circumstances are there more than one?
|
||||||
if status := req.Status.Conditions[0].Type; status != certsapi.CertificateApproved {
|
if status := req.Status.Conditions[0].Type; status != certsapi.CertificateApproved {
|
||||||
return nil, nil, fmt.Errorf("unexpected certificate status: %v", status)
|
return nil, nil, errors.Errorf("unexpected certificate status: %v", status)
|
||||||
}
|
}
|
||||||
|
|
||||||
cert, err := x509.ParseCertificate(req.Status.Certificate)
|
cert, err := x509.ParseCertificate(req.Status.Certificate)
|
||||||
|
@@ -18,7 +18,6 @@ package renewal
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
certutil "k8s.io/client-go/util/cert"
|
certutil "k8s.io/client-go/util/cert"
|
||||||
@@ -31,11 +30,11 @@ func RenewExistingCert(certsDir, baseName string, impl Interface) error {
|
|||||||
certificatePath, _ := pkiutil.PathsForCertAndKey(certsDir, baseName)
|
certificatePath, _ := pkiutil.PathsForCertAndKey(certsDir, baseName)
|
||||||
certs, err := certutil.CertsFromFile(certificatePath)
|
certs, err := certutil.CertsFromFile(certificatePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to load existing certificate %s: %v", baseName, err)
|
return errors.Wrapf(err, "failed to load existing certificate %s", baseName)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(certs) != 1 {
|
if len(certs) != 1 {
|
||||||
return fmt.Errorf("wanted exactly one certificate, got %d", len(certs))
|
return errors.Errorf("wanted exactly one certificate, got %d", len(certs))
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg := certToConfig(certs[0])
|
cfg := certToConfig(certs[0])
|
||||||
|
@@ -25,6 +25,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/util/version"
|
"k8s.io/apimachinery/pkg/util/version"
|
||||||
@@ -122,12 +123,12 @@ func createStaticPodFiles(manifestDir string, cfg *kubeadmapi.InitConfiguration,
|
|||||||
// retrives the StaticPodSpec for given component
|
// retrives the StaticPodSpec for given component
|
||||||
spec, exists := specs[componentName]
|
spec, exists := specs[componentName]
|
||||||
if !exists {
|
if !exists {
|
||||||
return fmt.Errorf("couldn't retrive StaticPodSpec for %s", componentName)
|
return errors.Errorf("couldn't retrive StaticPodSpec for %s", componentName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// writes the StaticPodSpec to disk
|
// writes the StaticPodSpec to disk
|
||||||
if err := staticpodutil.WriteStaticPodToDisk(componentName, manifestDir, spec); err != nil {
|
if err := staticpodutil.WriteStaticPodToDisk(componentName, manifestDir, spec); err != nil {
|
||||||
return fmt.Errorf("failed to create static pod manifest file for %q: %v", componentName, err)
|
return errors.Wrapf(err, "failed to create static pod manifest file for %q", componentName)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("[controlplane] wrote Static Pod manifest for component %s to %q\n", componentName, kubeadmconstants.GetStaticPodFilepath(componentName, manifestDir))
|
fmt.Printf("[controlplane] wrote Static Pod manifest for component %s to %q\n", componentName, kubeadmconstants.GetStaticPodFilepath(componentName, manifestDir))
|
||||||
|
@@ -23,6 +23,7 @@ import (
|
|||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
clientset "k8s.io/client-go/kubernetes"
|
clientset "k8s.io/client-go/kubernetes"
|
||||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
@@ -43,7 +44,7 @@ const (
|
|||||||
// upgrade - when the etcd cluster is already up and running (and the --initial-cluster flag have no impact)
|
// upgrade - when the etcd cluster is already up and running (and the --initial-cluster flag have no impact)
|
||||||
func CreateLocalEtcdStaticPodManifestFile(manifestDir string, cfg *kubeadmapi.InitConfiguration) error {
|
func CreateLocalEtcdStaticPodManifestFile(manifestDir string, cfg *kubeadmapi.InitConfiguration) error {
|
||||||
if cfg.ClusterConfiguration.Etcd.External != nil {
|
if cfg.ClusterConfiguration.Etcd.External != nil {
|
||||||
return fmt.Errorf("etcd static pod manifest cannot be generated for cluster using external etcd")
|
return errors.New("etcd static pod manifest cannot be generated for cluster using external etcd")
|
||||||
}
|
}
|
||||||
glog.V(1).Infoln("creating local etcd static pod manifest file")
|
glog.V(1).Infoln("creating local etcd static pod manifest file")
|
||||||
// gets etcd StaticPodSpec
|
// gets etcd StaticPodSpec
|
||||||
|
@@ -27,6 +27,7 @@ import (
|
|||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"k8s.io/client-go/tools/clientcmd"
|
"k8s.io/client-go/tools/clientcmd"
|
||||||
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||||||
@@ -129,7 +130,7 @@ func createKubeConfigFiles(outDir string, cfg *kubeadmapi.InitConfiguration, kub
|
|||||||
// retrives the KubeConfigSpec for given kubeConfigFileName
|
// retrives the KubeConfigSpec for given kubeConfigFileName
|
||||||
spec, exists := specs[kubeConfigFileName]
|
spec, exists := specs[kubeConfigFileName]
|
||||||
if !exists {
|
if !exists {
|
||||||
return fmt.Errorf("couldn't retrive KubeConfigSpec for %s", kubeConfigFileName)
|
return errors.Errorf("couldn't retrive KubeConfigSpec for %s", kubeConfigFileName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// builds the KubeConfig object
|
// builds the KubeConfig object
|
||||||
@@ -153,7 +154,7 @@ func getKubeConfigSpecs(cfg *kubeadmapi.InitConfiguration) (map[string]*kubeConf
|
|||||||
|
|
||||||
caCert, caKey, err := pkiutil.TryLoadCertAndKeyFromDisk(cfg.CertificatesDir, kubeadmconstants.CACertAndKeyBaseName)
|
caCert, caKey, err := pkiutil.TryLoadCertAndKeyFromDisk(cfg.CertificatesDir, kubeadmconstants.CACertAndKeyBaseName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("couldn't create a kubeconfig; the CA files couldn't be loaded: %v", err)
|
return nil, errors.Wrap(err, "couldn't create a kubeconfig; the CA files couldn't be loaded")
|
||||||
}
|
}
|
||||||
|
|
||||||
masterEndpoint, err := kubeadmutil.GetMasterEndpoint(cfg)
|
masterEndpoint, err := kubeadmutil.GetMasterEndpoint(cfg)
|
||||||
@@ -224,7 +225,7 @@ func buildKubeConfigFromSpec(spec *kubeConfigSpec, clustername string) (*clientc
|
|||||||
}
|
}
|
||||||
clientCert, clientKey, err := pkiutil.NewCertAndKey(spec.CACert, spec.ClientCertAuth.CAKey, &clientCertConfig)
|
clientCert, clientKey, err := pkiutil.NewCertAndKey(spec.CACert, spec.ClientCertAuth.CAKey, &clientCertConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failure while creating %s client certificate: %v", spec.ClientName, err)
|
return nil, errors.Wrapf(err, "failure while creating %s client certificate", spec.ClientName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a kubeconfig with the client certs
|
// create a kubeconfig with the client certs
|
||||||
@@ -249,7 +250,7 @@ func createKubeConfigFileIfNotExists(outDir, filename string, config *clientcmda
|
|||||||
if _, err := os.Stat(kubeConfigFilePath); os.IsNotExist(err) {
|
if _, err := os.Stat(kubeConfigFilePath); os.IsNotExist(err) {
|
||||||
err = kubeconfigutil.WriteToDisk(kubeConfigFilePath, config)
|
err = kubeconfigutil.WriteToDisk(kubeConfigFilePath, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to save kubeconfig file %s on disk: %v", kubeConfigFilePath, err)
|
return errors.Wrapf(err, "failed to save kubeconfig file %s on disk", kubeConfigFilePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("[kubeconfig] Wrote KubeConfig file to disk: %q\n", kubeConfigFilePath)
|
fmt.Printf("[kubeconfig] Wrote KubeConfig file to disk: %q\n", kubeConfigFilePath)
|
||||||
@@ -259,7 +260,7 @@ func createKubeConfigFileIfNotExists(outDir, filename string, config *clientcmda
|
|||||||
// The kubeconfig already exists, let's check if it has got the same CA and server URL
|
// The kubeconfig already exists, let's check if it has got the same CA and server URL
|
||||||
currentConfig, err := clientcmd.LoadFromFile(kubeConfigFilePath)
|
currentConfig, err := clientcmd.LoadFromFile(kubeConfigFilePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to load kubeconfig file %s that already exists on disk: %v", kubeConfigFilePath, err)
|
return errors.Wrapf(err, "failed to load kubeconfig file %s that already exists on disk", kubeConfigFilePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
expectedCtx := config.CurrentContext
|
expectedCtx := config.CurrentContext
|
||||||
@@ -269,11 +270,11 @@ func createKubeConfigFileIfNotExists(outDir, filename string, config *clientcmda
|
|||||||
|
|
||||||
// If the current CA cert on disk doesn't match the expected CA cert, error out because we have a file, but it's stale
|
// If the current CA cert on disk doesn't match the expected CA cert, error out because we have a file, but it's stale
|
||||||
if !bytes.Equal(currentConfig.Clusters[currentCluster].CertificateAuthorityData, config.Clusters[expectedCluster].CertificateAuthorityData) {
|
if !bytes.Equal(currentConfig.Clusters[currentCluster].CertificateAuthorityData, config.Clusters[expectedCluster].CertificateAuthorityData) {
|
||||||
return fmt.Errorf("a kubeconfig file %q exists already but has got the wrong CA cert", kubeConfigFilePath)
|
return errors.Errorf("a kubeconfig file %q exists already but has got the wrong CA cert", kubeConfigFilePath)
|
||||||
}
|
}
|
||||||
// If the current API Server location on disk doesn't match the expected API server, error out because we have a file, but it's stale
|
// If the current API Server location on disk doesn't match the expected API server, error out because we have a file, but it's stale
|
||||||
if currentConfig.Clusters[currentCluster].Server != config.Clusters[expectedCluster].Server {
|
if currentConfig.Clusters[currentCluster].Server != config.Clusters[expectedCluster].Server {
|
||||||
return fmt.Errorf("a kubeconfig file %q exists already but has got the wrong API Server URL", kubeConfigFilePath)
|
return errors.Errorf("a kubeconfig file %q exists already but has got the wrong API Server URL", kubeConfigFilePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
// kubeadm doesn't validate the existing kubeconfig file more than this (kubeadm trusts the client certs to be valid)
|
// kubeadm doesn't validate the existing kubeconfig file more than this (kubeadm trusts the client certs to be valid)
|
||||||
@@ -290,7 +291,7 @@ func WriteKubeConfigWithClientCert(out io.Writer, cfg *kubeadmapi.InitConfigurat
|
|||||||
// creates the KubeConfigSpecs, actualized for the current InitConfiguration
|
// creates the KubeConfigSpecs, actualized for the current InitConfiguration
|
||||||
caCert, caKey, err := pkiutil.TryLoadCertAndKeyFromDisk(cfg.CertificatesDir, kubeadmconstants.CACertAndKeyBaseName)
|
caCert, caKey, err := pkiutil.TryLoadCertAndKeyFromDisk(cfg.CertificatesDir, kubeadmconstants.CACertAndKeyBaseName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("couldn't create a kubeconfig; the CA files couldn't be loaded: %v", err)
|
return errors.Wrap(err, "couldn't create a kubeconfig; the CA files couldn't be loaded: %v")
|
||||||
}
|
}
|
||||||
|
|
||||||
masterEndpoint, err := kubeadmutil.GetMasterEndpoint(cfg)
|
masterEndpoint, err := kubeadmutil.GetMasterEndpoint(cfg)
|
||||||
@@ -317,7 +318,7 @@ func WriteKubeConfigWithToken(out io.Writer, cfg *kubeadmapi.InitConfiguration,
|
|||||||
// creates the KubeConfigSpecs, actualized for the current InitConfiguration
|
// creates the KubeConfigSpecs, actualized for the current InitConfiguration
|
||||||
caCert, _, err := pkiutil.TryLoadCertAndKeyFromDisk(cfg.CertificatesDir, kubeadmconstants.CACertAndKeyBaseName)
|
caCert, _, err := pkiutil.TryLoadCertAndKeyFromDisk(cfg.CertificatesDir, kubeadmconstants.CACertAndKeyBaseName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("couldn't create a kubeconfig; the CA files couldn't be loaded: %v", err)
|
return errors.Wrapf(err, "couldn't create a kubeconfig; the CA files couldn't be loaded")
|
||||||
}
|
}
|
||||||
|
|
||||||
masterEndpoint, err := kubeadmutil.GetMasterEndpoint(cfg)
|
masterEndpoint, err := kubeadmutil.GetMasterEndpoint(cfg)
|
||||||
@@ -349,7 +350,7 @@ func writeKubeConfigFromSpec(out io.Writer, spec *kubeConfigSpec, clustername st
|
|||||||
// writes the KubeConfig to disk if it not exists
|
// writes the KubeConfig to disk if it not exists
|
||||||
configBytes, err := clientcmd.Write(*config)
|
configBytes, err := clientcmd.Write(*config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failure while serializing admin kubeconfig: %v", err)
|
return errors.Wrap(err, "failure while serializing admin kubeconfig")
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprintln(out, string(configBytes))
|
fmt.Fprintln(out, string(configBytes))
|
||||||
|
@@ -22,6 +22,8 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
rbac "k8s.io/api/rbac/v1"
|
rbac "k8s.io/api/rbac/v1"
|
||||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
@@ -77,7 +79,7 @@ func CreateConfigMap(cfg *kubeadmapi.InitConfiguration, client clientset.Interfa
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err := createConfigMapRBACRules(client, k8sVersion); err != nil {
|
if err := createConfigMapRBACRules(client, k8sVersion); err != nil {
|
||||||
return fmt.Errorf("error creating kubelet configuration configmap RBAC rules: %v", err)
|
return errors.Wrap(err, "error creating kubelet configuration configmap RBAC rules")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -159,11 +161,11 @@ func writeConfigBytesToDisk(b []byte, kubeletDir string) error {
|
|||||||
|
|
||||||
// creates target folder if not already exists
|
// creates target folder if not already exists
|
||||||
if err := os.MkdirAll(kubeletDir, 0700); err != nil {
|
if err := os.MkdirAll(kubeletDir, 0700); err != nil {
|
||||||
return fmt.Errorf("failed to create directory %q: %v", kubeletDir, err)
|
return errors.Wrapf(err, "failed to create directory %q", kubeletDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := ioutil.WriteFile(configFile, b, 0644); err != nil {
|
if err := ioutil.WriteFile(configFile, b, 0644); err != nil {
|
||||||
return fmt.Errorf("failed to write kubelet configuration to the file %q: %v", configFile, err)
|
return errors.Wrapf(err, "failed to write kubelet configuration to the file %q", configFile)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@@ -19,6 +19,8 @@ package kubelet
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/util/version"
|
"k8s.io/apimachinery/pkg/util/version"
|
||||||
@@ -39,7 +41,7 @@ func EnableDynamicConfigForNode(client clientset.Interface, nodeName string, kub
|
|||||||
|
|
||||||
_, err := client.CoreV1().ConfigMaps(metav1.NamespaceSystem).Get(configMapName, metav1.GetOptions{})
|
_, err := client.CoreV1().ConfigMaps(metav1.NamespaceSystem).Get(configMapName, metav1.GetOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("couldn't get the kubelet configuration ConfigMap: %v", err)
|
return errors.Wrap(err, "couldn't get the kubelet configuration ConfigMap")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loop on every falsy return. Return with an error if raised. Exit successfully if true is returned.
|
// Loop on every falsy return. Return with an error if raised. Exit successfully if true is returned.
|
||||||
|
@@ -24,6 +24,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1"
|
kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||||
@@ -123,10 +125,10 @@ func writeKubeletFlagBytesToDisk(b []byte, kubeletDir string) error {
|
|||||||
|
|
||||||
// creates target folder if not already exists
|
// creates target folder if not already exists
|
||||||
if err := os.MkdirAll(kubeletDir, 0700); err != nil {
|
if err := os.MkdirAll(kubeletDir, 0700); err != nil {
|
||||||
return fmt.Errorf("failed to create directory %q: %v", kubeletDir, err)
|
return errors.Wrapf(err, "failed to create directory %q", kubeletDir)
|
||||||
}
|
}
|
||||||
if err := ioutil.WriteFile(kubeletEnvFilePath, b, 0644); err != nil {
|
if err := ioutil.WriteFile(kubeletEnvFilePath, b, 0644); err != nil {
|
||||||
return fmt.Errorf("failed to write kubelet configuration to the file %q: %v", kubeletEnvFilePath, err)
|
return errors.Wrapf(err, "failed to write kubelet configuration to the file %q", kubeletEnvFilePath)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@@ -79,7 +79,7 @@ var (
|
|||||||
errCgroupExecer = fakeExecer{
|
errCgroupExecer = fakeExecer{
|
||||||
ioMap: map[string]fakeCmd{
|
ioMap: map[string]fakeCmd{
|
||||||
"docker info": {
|
"docker info": {
|
||||||
err: fmt.Errorf("no such binary: docker"),
|
err: errors.New("no such binary: docker"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@@ -24,6 +24,7 @@ import (
|
|||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
apps "k8s.io/api/apps/v1"
|
apps "k8s.io/api/apps/v1"
|
||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
@@ -111,7 +112,7 @@ func CreateSelfHostedControlPlane(manifestsDir, kubeConfigDir string, cfg *kubea
|
|||||||
// Remove the old Static Pod manifest if not dryrunning
|
// Remove the old Static Pod manifest if not dryrunning
|
||||||
if !dryRun {
|
if !dryRun {
|
||||||
if err := os.RemoveAll(manifestPath); err != nil {
|
if err := os.RemoveAll(manifestPath); err != nil {
|
||||||
return fmt.Errorf("unable to delete static pod manifest for %s [%v]", componentName, err)
|
return errors.Wrapf(err, "unable to delete static pod manifest for %s ", componentName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,18 +180,18 @@ func BuildSelfHostedComponentLabelQuery(componentName string) string {
|
|||||||
func loadPodSpecFromFile(filePath string) (*v1.PodSpec, error) {
|
func loadPodSpecFromFile(filePath string) (*v1.PodSpec, error) {
|
||||||
podDef, err := ioutil.ReadFile(filePath)
|
podDef, err := ioutil.ReadFile(filePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to read file path %s: %+v", filePath, err)
|
return nil, errors.Wrapf(err, "failed to read file path %s", filePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(podDef) == 0 {
|
if len(podDef) == 0 {
|
||||||
return nil, fmt.Errorf("file was empty: %s", filePath)
|
return nil, errors.Errorf("file was empty: %s", filePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
codec := clientscheme.Codecs.UniversalDecoder()
|
codec := clientscheme.Codecs.UniversalDecoder()
|
||||||
pod := &v1.Pod{}
|
pod := &v1.Pod{}
|
||||||
|
|
||||||
if err = runtime.DecodeInto(codec, podDef, pod); err != nil {
|
if err = runtime.DecodeInto(codec, podDef, pod); err != nil {
|
||||||
return nil, fmt.Errorf("failed decoding pod: %v", err)
|
return nil, errors.Wrap(err, "failed decoding pod")
|
||||||
}
|
}
|
||||||
|
|
||||||
return &pod.Spec, nil
|
return &pod.Spec, nil
|
||||||
|
@@ -18,11 +18,12 @@ package selfhosting
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
apps "k8s.io/api/apps/v1"
|
apps "k8s.io/api/apps/v1"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/util"
|
"k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||||
@@ -588,13 +589,13 @@ spec:
|
|||||||
func createTempFileWithContent(content []byte) (string, error) {
|
func createTempFileWithContent(content []byte) (string, error) {
|
||||||
tempFile, err := ioutil.TempFile("", "")
|
tempFile, err := ioutil.TempFile("", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("cannot create temporary file: %v", err)
|
return "", errors.Wrap(err, "cannot create temporary file")
|
||||||
}
|
}
|
||||||
if _, err = tempFile.Write([]byte(content)); err != nil {
|
if _, err = tempFile.Write([]byte(content)); err != nil {
|
||||||
return "", fmt.Errorf("cannot save temporary file: %v", err)
|
return "", errors.Wrap(err, "cannot save temporary file")
|
||||||
}
|
}
|
||||||
if err = tempFile.Close(); err != nil {
|
if err = tempFile.Close(); err != nil {
|
||||||
return "", fmt.Errorf("cannot close temporary file: %v", err)
|
return "", errors.Wrap(err, "cannot close temporary file")
|
||||||
}
|
}
|
||||||
return tempFile.Name(), nil
|
return tempFile.Name(), nil
|
||||||
}
|
}
|
||||||
|
@@ -23,6 +23,8 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/coreos/etcd/clientv3"
|
"github.com/coreos/etcd/clientv3"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
apps "k8s.io/api/apps/v1"
|
apps "k8s.io/api/apps/v1"
|
||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
@@ -89,7 +91,7 @@ func (f fakeEtcdClient) GetClusterStatus() (map[string]*clientv3.StatusResponse,
|
|||||||
func (f fakeEtcdClient) GetVersion() (string, error) {
|
func (f fakeEtcdClient) GetVersion() (string, error) {
|
||||||
versions, _ := f.GetClusterVersions()
|
versions, _ := f.GetClusterVersions()
|
||||||
if f.mismatchedVersions {
|
if f.mismatchedVersions {
|
||||||
return "", fmt.Errorf("etcd cluster contains endpoints with mismatched versions: %v", versions)
|
return "", errors.Errorf("etcd cluster contains endpoints with mismatched versions: %v", versions)
|
||||||
}
|
}
|
||||||
return "3.1.12", nil
|
return "3.1.12", nil
|
||||||
}
|
}
|
||||||
|
@@ -104,7 +104,7 @@ func apiServerHealthy(client clientset.Interface) error {
|
|||||||
}
|
}
|
||||||
client.Discovery().RESTClient().Get().AbsPath("/healthz").Do().StatusCode(&healthStatus)
|
client.Discovery().RESTClient().Get().AbsPath("/healthz").Do().StatusCode(&healthStatus)
|
||||||
if healthStatus != http.StatusOK {
|
if healthStatus != http.StatusOK {
|
||||||
return fmt.Errorf("the API Server is unhealthy; /healthz didn't return %q", "ok")
|
return errors.Errorf("the API Server is unhealthy; /healthz didn't return %q", "ok")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -127,7 +127,7 @@ func masterNodesReady(client clientset.Interface) error {
|
|||||||
|
|
||||||
notReadyMasters := getNotReadyNodes(masters.Items)
|
notReadyMasters := getNotReadyNodes(masters.Items)
|
||||||
if len(notReadyMasters) != 0 {
|
if len(notReadyMasters) != 0 {
|
||||||
return fmt.Errorf("there are NotReady masters in the cluster: %v", notReadyMasters)
|
return errors.Errorf("there are NotReady masters in the cluster: %v", notReadyMasters)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -140,7 +140,7 @@ func controlPlaneHealth(client clientset.Interface) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(notReadyDaemonSets) != 0 {
|
if len(notReadyDaemonSets) != 0 {
|
||||||
return fmt.Errorf("there are control plane DaemonSets in the cluster that are not ready: %v", notReadyDaemonSets)
|
return errors.Errorf("there are control plane DaemonSets in the cluster that are not ready: %v", notReadyDaemonSets)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -157,7 +157,7 @@ func staticPodManifestHealth(_ clientset.Interface) error {
|
|||||||
if len(nonExistentManifests) == 0 {
|
if len(nonExistentManifests) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("The control plane seems to be Static Pod-hosted, but some of the manifests don't seem to exist on disk. This probably means you're running 'kubeadm upgrade' on a remote machine, which is not supported for a Static Pod-hosted cluster. Manifest files not found: %v", nonExistentManifests)
|
return errors.Errorf("The control plane seems to be Static Pod-hosted, but some of the manifests don't seem to exist on disk. This probably means you're running 'kubeadm upgrade' on a remote machine, which is not supported for a Static Pod-hosted cluster. Manifest files not found: %v", nonExistentManifests)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsControlPlaneSelfHosted returns whether the control plane is self hosted or not
|
// IsControlPlaneSelfHosted returns whether the control plane is self hosted or not
|
||||||
@@ -178,11 +178,11 @@ func getNotReadyDaemonSets(client clientset.Interface) ([]error, error) {
|
|||||||
dsName := constants.AddSelfHostedPrefix(component)
|
dsName := constants.AddSelfHostedPrefix(component)
|
||||||
ds, err := client.AppsV1().DaemonSets(metav1.NamespaceSystem).Get(dsName, metav1.GetOptions{})
|
ds, err := client.AppsV1().DaemonSets(metav1.NamespaceSystem).Get(dsName, metav1.GetOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("couldn't get daemonset %q in the %s namespace", dsName, metav1.NamespaceSystem)
|
return nil, errors.Errorf("couldn't get daemonset %q in the %s namespace", dsName, metav1.NamespaceSystem)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := daemonSetHealth(&ds.Status); err != nil {
|
if err := daemonSetHealth(&ds.Status); err != nil {
|
||||||
notReadyDaemonSets = append(notReadyDaemonSets, fmt.Errorf("DaemonSet %q not healthy: %v", dsName, err))
|
notReadyDaemonSets = append(notReadyDaemonSets, errors.Wrapf(err, "DaemonSet %q not healthy", dsName))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return notReadyDaemonSets, nil
|
return notReadyDaemonSets, nil
|
||||||
@@ -191,7 +191,8 @@ func getNotReadyDaemonSets(client clientset.Interface) ([]error, error) {
|
|||||||
// daemonSetHealth is a helper function for getting the health of a DaemonSet's status
|
// daemonSetHealth is a helper function for getting the health of a DaemonSet's status
|
||||||
func daemonSetHealth(dsStatus *apps.DaemonSetStatus) error {
|
func daemonSetHealth(dsStatus *apps.DaemonSetStatus) error {
|
||||||
if dsStatus.CurrentNumberScheduled != dsStatus.DesiredNumberScheduled {
|
if dsStatus.CurrentNumberScheduled != dsStatus.DesiredNumberScheduled {
|
||||||
return fmt.Errorf("current number of scheduled Pods ('%d') doesn't match the amount of desired Pods ('%d')", dsStatus.CurrentNumberScheduled, dsStatus.DesiredNumberScheduled)
|
return errors.Errorf("current number of scheduled Pods ('%d') doesn't match the amount of desired Pods ('%d')",
|
||||||
|
dsStatus.CurrentNumberScheduled, dsStatus.DesiredNumberScheduled)
|
||||||
}
|
}
|
||||||
if dsStatus.NumberAvailable == 0 {
|
if dsStatus.NumberAvailable == 0 {
|
||||||
return errors.New("no available Pods for DaemonSet")
|
return errors.New("no available Pods for DaemonSet")
|
||||||
|
@@ -17,9 +17,10 @@ limitations under the License.
|
|||||||
package upgrade
|
package upgrade
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/util/version"
|
"k8s.io/apimachinery/pkg/util/version"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||||
)
|
)
|
||||||
@@ -52,32 +53,32 @@ func EnforceVersionPolicies(versionGetter VersionGetter, newK8sVersionStr string
|
|||||||
clusterVersionStr, clusterVersion, err := versionGetter.ClusterVersion()
|
clusterVersionStr, clusterVersion, err := versionGetter.ClusterVersion()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// This case can't be forced: kubeadm has to be able to lookup cluster version for upgrades to work
|
// This case can't be forced: kubeadm has to be able to lookup cluster version for upgrades to work
|
||||||
skewErrors.Mandatory = append(skewErrors.Mandatory, fmt.Errorf("Unable to fetch cluster version: %v", err))
|
skewErrors.Mandatory = append(skewErrors.Mandatory, errors.Wrap(err, "Unable to fetch cluster version"))
|
||||||
return skewErrors
|
return skewErrors
|
||||||
}
|
}
|
||||||
|
|
||||||
kubeadmVersionStr, kubeadmVersion, err := versionGetter.KubeadmVersion()
|
kubeadmVersionStr, kubeadmVersion, err := versionGetter.KubeadmVersion()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// This case can't be forced: kubeadm has to be able to lookup its version for upgrades to work
|
// This case can't be forced: kubeadm has to be able to lookup its version for upgrades to work
|
||||||
skewErrors.Mandatory = append(skewErrors.Mandatory, fmt.Errorf("Unable to fetch kubeadm version: %v", err))
|
skewErrors.Mandatory = append(skewErrors.Mandatory, errors.Wrap(err, "Unable to fetch kubeadm version"))
|
||||||
return skewErrors
|
return skewErrors
|
||||||
}
|
}
|
||||||
|
|
||||||
kubeletVersions, err := versionGetter.KubeletVersions()
|
kubeletVersions, err := versionGetter.KubeletVersions()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// This is a non-critical error; continue although kubeadm couldn't look this up
|
// This is a non-critical error; continue although kubeadm couldn't look this up
|
||||||
skewErrors.Skippable = append(skewErrors.Skippable, fmt.Errorf("Unable to fetch kubelet version: %v", err))
|
skewErrors.Skippable = append(skewErrors.Skippable, errors.Wrap(err, "Unable to fetch kubelet version"))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure the new version is a supported version (higher than the minimum one supported)
|
// Make sure the new version is a supported version (higher than the minimum one supported)
|
||||||
if constants.MinimumControlPlaneVersion.AtLeast(newK8sVersion) {
|
if constants.MinimumControlPlaneVersion.AtLeast(newK8sVersion) {
|
||||||
// This must not happen, kubeadm always supports a minimum version; and we can't go below that
|
// This must not happen, kubeadm always supports a minimum version; and we can't go below that
|
||||||
skewErrors.Mandatory = append(skewErrors.Mandatory, fmt.Errorf("Specified version to upgrade to %q is equal to or lower than the minimum supported version %q. Please specify a higher version to upgrade to", newK8sVersionStr, clusterVersionStr))
|
skewErrors.Mandatory = append(skewErrors.Mandatory, errors.Errorf("Specified version to upgrade to %q is equal to or lower than the minimum supported version %q. Please specify a higher version to upgrade to", newK8sVersionStr, clusterVersionStr))
|
||||||
}
|
}
|
||||||
|
|
||||||
// kubeadm doesn't support upgrades between two minor versions; e.g. a v1.7 -> v1.9 upgrade is not supported right away
|
// kubeadm doesn't support upgrades between two minor versions; e.g. a v1.7 -> v1.9 upgrade is not supported right away
|
||||||
if newK8sVersion.Minor() > clusterVersion.Minor()+MaximumAllowedMinorVersionUpgradeSkew {
|
if newK8sVersion.Minor() > clusterVersion.Minor()+MaximumAllowedMinorVersionUpgradeSkew {
|
||||||
tooLargeUpgradeSkewErr := fmt.Errorf("Specified version to upgrade to %q is too high; kubeadm can upgrade only %d minor version at a time", newK8sVersionStr, MaximumAllowedMinorVersionUpgradeSkew)
|
tooLargeUpgradeSkewErr := errors.Errorf("Specified version to upgrade to %q is too high; kubeadm can upgrade only %d minor version at a time", newK8sVersionStr, MaximumAllowedMinorVersionUpgradeSkew)
|
||||||
// If the version that we're about to upgrade to is a released version, we should fully enforce this policy
|
// If the version that we're about to upgrade to is a released version, we should fully enforce this policy
|
||||||
// If the version is a CI/dev/experimental version, it's okay to jump two minor version steps, but then require the -f flag
|
// If the version is a CI/dev/experimental version, it's okay to jump two minor version steps, but then require the -f flag
|
||||||
if len(newK8sVersion.PreRelease()) == 0 {
|
if len(newK8sVersion.PreRelease()) == 0 {
|
||||||
@@ -89,7 +90,7 @@ func EnforceVersionPolicies(versionGetter VersionGetter, newK8sVersionStr string
|
|||||||
|
|
||||||
// kubeadm doesn't support downgrades between two minor versions; e.g. a v1.9 -> v1.7 downgrade is not supported right away
|
// kubeadm doesn't support downgrades between two minor versions; e.g. a v1.9 -> v1.7 downgrade is not supported right away
|
||||||
if newK8sVersion.Minor() < clusterVersion.Minor()-MaximumAllowedMinorVersionDowngradeSkew {
|
if newK8sVersion.Minor() < clusterVersion.Minor()-MaximumAllowedMinorVersionDowngradeSkew {
|
||||||
tooLargeDowngradeSkewErr := fmt.Errorf("Specified version to downgrade to %q is too low; kubeadm can downgrade only %d minor version at a time", newK8sVersionStr, MaximumAllowedMinorVersionDowngradeSkew)
|
tooLargeDowngradeSkewErr := errors.Errorf("Specified version to downgrade to %q is too low; kubeadm can downgrade only %d minor version at a time", newK8sVersionStr, MaximumAllowedMinorVersionDowngradeSkew)
|
||||||
// If the version that we're about to downgrade to is a released version, we should fully enforce this policy
|
// If the version that we're about to downgrade to is a released version, we should fully enforce this policy
|
||||||
// If the version is a CI/dev/experimental version, it's okay to jump two minor version steps, but then require the -f flag
|
// If the version is a CI/dev/experimental version, it's okay to jump two minor version steps, but then require the -f flag
|
||||||
if len(newK8sVersion.PreRelease()) == 0 {
|
if len(newK8sVersion.PreRelease()) == 0 {
|
||||||
@@ -102,7 +103,7 @@ func EnforceVersionPolicies(versionGetter VersionGetter, newK8sVersionStr string
|
|||||||
// If the kubeadm version is lower than what we want to upgrade to; error
|
// If the kubeadm version is lower than what we want to upgrade to; error
|
||||||
if kubeadmVersion.LessThan(newK8sVersion) {
|
if kubeadmVersion.LessThan(newK8sVersion) {
|
||||||
if newK8sVersion.Minor() > kubeadmVersion.Minor() {
|
if newK8sVersion.Minor() > kubeadmVersion.Minor() {
|
||||||
tooLargeKubeadmSkew := fmt.Errorf("Specified version to upgrade to %q is at least one minor release higher than the kubeadm minor release (%d > %d). Such an upgrade is not supported", newK8sVersionStr, newK8sVersion.Minor(), kubeadmVersion.Minor())
|
tooLargeKubeadmSkew := errors.Errorf("Specified version to upgrade to %q is at least one minor release higher than the kubeadm minor release (%d > %d). Such an upgrade is not supported", newK8sVersionStr, newK8sVersion.Minor(), kubeadmVersion.Minor())
|
||||||
// This is unsupported; kubeadm has no idea how it should handle a newer minor release than itself
|
// This is unsupported; kubeadm has no idea how it should handle a newer minor release than itself
|
||||||
// If the version is a CI/dev/experimental version though, lower the severity of this check, but then require the -f flag
|
// If the version is a CI/dev/experimental version though, lower the severity of this check, but then require the -f flag
|
||||||
if len(newK8sVersion.PreRelease()) == 0 {
|
if len(newK8sVersion.PreRelease()) == 0 {
|
||||||
@@ -112,13 +113,13 @@ func EnforceVersionPolicies(versionGetter VersionGetter, newK8sVersionStr string
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Upgrading to a higher patch version than kubeadm is ok if the user specifies --force. Not recommended, but possible.
|
// Upgrading to a higher patch version than kubeadm is ok if the user specifies --force. Not recommended, but possible.
|
||||||
skewErrors.Skippable = append(skewErrors.Skippable, fmt.Errorf("Specified version to upgrade to %q is higher than the kubeadm version %q. Upgrade kubeadm first using the tool you used to install kubeadm", newK8sVersionStr, kubeadmVersionStr))
|
skewErrors.Skippable = append(skewErrors.Skippable, errors.Errorf("Specified version to upgrade to %q is higher than the kubeadm version %q. Upgrade kubeadm first using the tool you used to install kubeadm", newK8sVersionStr, kubeadmVersionStr))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if kubeadmVersion.Major() > newK8sVersion.Major() ||
|
if kubeadmVersion.Major() > newK8sVersion.Major() ||
|
||||||
kubeadmVersion.Minor() > newK8sVersion.Minor() {
|
kubeadmVersion.Minor() > newK8sVersion.Minor() {
|
||||||
skewErrors.Skippable = append(skewErrors.Skippable, fmt.Errorf("Kubeadm version %s can only be used to upgrade to Kubernetes version %d.%d", kubeadmVersionStr, kubeadmVersion.Major(), kubeadmVersion.Minor()))
|
skewErrors.Skippable = append(skewErrors.Skippable, errors.Errorf("Kubeadm version %s can only be used to upgrade to Kubernetes version %d.%d", kubeadmVersionStr, kubeadmVersion.Major(), kubeadmVersion.Minor()))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Detect if the version is unstable and the user didn't allow that
|
// Detect if the version is unstable and the user didn't allow that
|
||||||
@@ -159,7 +160,7 @@ func detectUnstableVersionError(newK8sVersion *version.Version, newK8sVersionStr
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Errorf("Specified version to upgrade to %q is an unstable version and such upgrades weren't allowed via setting the --allow-*-upgrades flags", newK8sVersionStr)
|
return errors.Errorf("Specified version to upgrade to %q is an unstable version and such upgrades weren't allowed via setting the --allow-*-upgrades flags", newK8sVersionStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// detectTooOldKubelets errors out if the kubelet versions are so old that an unsupported skew would happen if the cluster was upgraded
|
// detectTooOldKubelets errors out if the kubelet versions are so old that an unsupported skew would happen if the cluster was upgraded
|
||||||
@@ -169,7 +170,7 @@ func detectTooOldKubelets(newK8sVersion *version.Version, kubeletVersions map[st
|
|||||||
|
|
||||||
kubeletVersion, err := version.ParseSemantic(versionStr)
|
kubeletVersion, err := version.ParseSemantic(versionStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("couldn't parse kubelet version %s", versionStr)
|
return errors.Errorf("couldn't parse kubelet version %s", versionStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
if newK8sVersion.Minor() > kubeletVersion.Minor()+MaximumAllowedMinorVersionKubeletSkew {
|
if newK8sVersion.Minor() > kubeletVersion.Minor()+MaximumAllowedMinorVersionKubeletSkew {
|
||||||
@@ -180,5 +181,5 @@ func detectTooOldKubelets(newK8sVersion *version.Version, kubeletVersions map[st
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Errorf("There are kubelets in this cluster that are too old that have these versions %v", tooOldKubeletVersions)
|
return errors.Errorf("There are kubelets in this cluster that are too old that have these versions %v", tooOldKubeletVersions)
|
||||||
}
|
}
|
||||||
|
@@ -23,6 +23,8 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
pkgerrors "github.com/pkg/errors"
|
||||||
|
|
||||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/util/errors"
|
"k8s.io/apimachinery/pkg/util/errors"
|
||||||
@@ -62,7 +64,7 @@ func PerformPostUpgradeTasks(client clientset.Interface, cfg *kubeadmapi.InitCon
|
|||||||
|
|
||||||
// Create the new, version-branched kubelet ComponentConfig ConfigMap
|
// Create the new, version-branched kubelet ComponentConfig ConfigMap
|
||||||
if err := kubeletphase.CreateConfigMap(cfg, client); err != nil {
|
if err := kubeletphase.CreateConfigMap(cfg, client); err != nil {
|
||||||
errs = append(errs, fmt.Errorf("error creating kubelet configuration ConfigMap: %v", err))
|
errs = append(errs, pkgerrors.Wrap(err, "error creating kubelet configuration ConfigMap"))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the new kubelet config down to disk and the env file if needed
|
// Write the new kubelet config down to disk and the env file if needed
|
||||||
@@ -74,7 +76,7 @@ func PerformPostUpgradeTasks(client clientset.Interface, cfg *kubeadmapi.InitCon
|
|||||||
// --cri-socket.
|
// --cri-socket.
|
||||||
// TODO: In the future we want to use something more official like NodeStatus or similar for detecting this properly
|
// TODO: In the future we want to use something more official like NodeStatus or similar for detecting this properly
|
||||||
if err := patchnodephase.AnnotateCRISocket(client, cfg.NodeRegistration.Name, cfg.NodeRegistration.CRISocket); err != nil {
|
if err := patchnodephase.AnnotateCRISocket(client, cfg.NodeRegistration.Name, cfg.NodeRegistration.CRISocket); err != nil {
|
||||||
errs = append(errs, fmt.Errorf("error uploading crisocket: %v", err))
|
errs = append(errs, pkgerrors.Wrap(err, "error uploading crisocket"))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create/update RBAC rules that makes the bootstrap tokens able to post CSRs
|
// Create/update RBAC rules that makes the bootstrap tokens able to post CSRs
|
||||||
@@ -144,7 +146,7 @@ func removeOldDNSDeploymentIfAnotherDNSIsUsed(cfg *kubeadmapi.InitConfiguration,
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if dnsDeployment.Status.ReadyReplicas == 0 {
|
if dnsDeployment.Status.ReadyReplicas == 0 {
|
||||||
return fmt.Errorf("the DNS deployment isn't ready yet")
|
return pkgerrors.New("the DNS deployment isn't ready yet")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,7 +168,7 @@ func upgradeToSelfHosting(client clientset.Interface, cfg *kubeadmapi.InitConfig
|
|||||||
// kubeadm will now convert the static Pod-hosted control plane into a self-hosted one
|
// kubeadm will now convert the static Pod-hosted control plane into a self-hosted one
|
||||||
fmt.Println("[self-hosted] Creating self-hosted control plane.")
|
fmt.Println("[self-hosted] Creating self-hosted control plane.")
|
||||||
if err := selfhosting.CreateSelfHostedControlPlane(kubeadmconstants.GetStaticPodDirectory(), kubeadmconstants.KubernetesDir, cfg, client, waiter, dryRun); err != nil {
|
if err := selfhosting.CreateSelfHostedControlPlane(kubeadmconstants.GetStaticPodDirectory(), kubeadmconstants.KubernetesDir, cfg, client, waiter, dryRun); err != nil {
|
||||||
return fmt.Errorf("error creating self hosted control plane: %v", err)
|
return pkgerrors.Wrap(err, "error creating self hosted control plane")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -178,7 +180,7 @@ func BackupAPIServerCertIfNeeded(cfg *kubeadmapi.InitConfiguration, dryRun bool)
|
|||||||
shouldBackup, err := shouldBackupAPIServerCertAndKey(certAndKeyDir)
|
shouldBackup, err := shouldBackupAPIServerCertAndKey(certAndKeyDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Don't fail the upgrade phase if failing to determine to backup kube-apiserver cert and key.
|
// Don't fail the upgrade phase if failing to determine to backup kube-apiserver cert and key.
|
||||||
return fmt.Errorf("[postupgrade] WARNING: failed to determine to backup kube-apiserver cert and key: %v", err)
|
return pkgerrors.Wrap(err, "[postupgrade] WARNING: failed to determine to backup kube-apiserver cert and key")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !shouldBackup {
|
if !shouldBackup {
|
||||||
@@ -216,7 +218,7 @@ func writeKubeletConfigFiles(client clientset.Interface, cfg *kubeadmapi.InitCon
|
|||||||
// *would* post the new kubelet-config-1.X configmap that doesn't exist now when we're trying to download it
|
// *would* post the new kubelet-config-1.X configmap that doesn't exist now when we're trying to download it
|
||||||
// again.
|
// again.
|
||||||
if !(apierrors.IsNotFound(err) && dryRun) {
|
if !(apierrors.IsNotFound(err) && dryRun) {
|
||||||
errs = append(errs, fmt.Errorf("error downloading kubelet configuration from the ConfigMap: %v", err))
|
errs = append(errs, pkgerrors.Wrap(err, "error downloading kubelet configuration from the ConfigMap"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,7 +232,7 @@ func writeKubeletConfigFiles(client clientset.Interface, cfg *kubeadmapi.InitCon
|
|||||||
// as we handle that ourselves in the markmaster phase
|
// as we handle that ourselves in the markmaster phase
|
||||||
// TODO: Maybe we want to do that some time in the future, in order to remove some logic from the markmaster phase?
|
// TODO: Maybe we want to do that some time in the future, in order to remove some logic from the markmaster phase?
|
||||||
if err := kubeletphase.WriteKubeletDynamicEnvFile(&cfg.NodeRegistration, cfg.FeatureGates, false, kubeletDir); err != nil {
|
if err := kubeletphase.WriteKubeletDynamicEnvFile(&cfg.NodeRegistration, cfg.FeatureGates, false, kubeletDir); err != nil {
|
||||||
errs = append(errs, fmt.Errorf("error writing a dynamic environment file for the kubelet: %v", err))
|
errs = append(errs, pkgerrors.Wrap(err, "error writing a dynamic environment file for the kubelet"))
|
||||||
}
|
}
|
||||||
|
|
||||||
if dryRun { // Print what contents would be written
|
if dryRun { // Print what contents would be written
|
||||||
@@ -262,7 +264,7 @@ func getKubeletDir(dryRun bool) (string, error) {
|
|||||||
func backupAPIServerCertAndKey(certAndKeyDir string) error {
|
func backupAPIServerCertAndKey(certAndKeyDir string) error {
|
||||||
subDir := filepath.Join(certAndKeyDir, "expired")
|
subDir := filepath.Join(certAndKeyDir, "expired")
|
||||||
if err := os.Mkdir(subDir, 0766); err != nil {
|
if err := os.Mkdir(subDir, 0766); err != nil {
|
||||||
return fmt.Errorf("failed to created backup directory %s: %v", subDir, err)
|
return pkgerrors.Wrapf(err, "failed to created backup directory %s", subDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
filesToMove := map[string]string{
|
filesToMove := map[string]string{
|
||||||
@@ -292,7 +294,7 @@ func rollbackFiles(files map[string]string, originalErr error) error {
|
|||||||
errs = append(errs, err)
|
errs = append(errs, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return fmt.Errorf("couldn't move these files: %v. Got errors: %v", files, errors.NewAggregate(errs))
|
return pkgerrors.Errorf("couldn't move these files: %v. Got errors: %v", files, errors.NewAggregate(errs))
|
||||||
}
|
}
|
||||||
|
|
||||||
// shouldBackupAPIServerCertAndKey checks if the cert of kube-apiserver will be expired in 180 days.
|
// shouldBackupAPIServerCertAndKey checks if the cert of kube-apiserver will be expired in 180 days.
|
||||||
@@ -300,10 +302,10 @@ func shouldBackupAPIServerCertAndKey(certAndKeyDir string) (bool, error) {
|
|||||||
apiServerCert := filepath.Join(certAndKeyDir, kubeadmconstants.APIServerCertName)
|
apiServerCert := filepath.Join(certAndKeyDir, kubeadmconstants.APIServerCertName)
|
||||||
certs, err := certutil.CertsFromFile(apiServerCert)
|
certs, err := certutil.CertsFromFile(apiServerCert)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, fmt.Errorf("couldn't load the certificate file %s: %v", apiServerCert, err)
|
return false, pkgerrors.Wrapf(err, "couldn't load the certificate file %s", apiServerCert)
|
||||||
}
|
}
|
||||||
if len(certs) == 0 {
|
if len(certs) == 0 {
|
||||||
return false, fmt.Errorf("no certificate data found")
|
return false, pkgerrors.New("no certificate data found")
|
||||||
}
|
}
|
||||||
|
|
||||||
if time.Now().Sub(certs[0].NotBefore) > expiry {
|
if time.Now().Sub(certs[0].NotBefore) > expiry {
|
||||||
|
@@ -20,6 +20,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
apps "k8s.io/api/apps/v1"
|
apps "k8s.io/api/apps/v1"
|
||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
@@ -69,7 +71,7 @@ func (d *DaemonSetPrepuller) CreateFunc(component string) error {
|
|||||||
|
|
||||||
// Create the DaemonSet in the API Server
|
// Create the DaemonSet in the API Server
|
||||||
if err := apiclient.CreateOrUpdateDaemonSet(d.client, ds); err != nil {
|
if err := apiclient.CreateOrUpdateDaemonSet(d.client, ds); err != nil {
|
||||||
return fmt.Errorf("unable to create a DaemonSet for prepulling the component %q: %v", component, err)
|
return errors.Wrapf(err, "unable to create a DaemonSet for prepulling the component %q", component)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -84,7 +86,7 @@ func (d *DaemonSetPrepuller) WaitFunc(component string) {
|
|||||||
func (d *DaemonSetPrepuller) DeleteFunc(component string) error {
|
func (d *DaemonSetPrepuller) DeleteFunc(component string) error {
|
||||||
dsName := addPrepullPrefix(component)
|
dsName := addPrepullPrefix(component)
|
||||||
if err := apiclient.DeleteDaemonSetForeground(d.client, metav1.NamespaceSystem, dsName); err != nil {
|
if err := apiclient.DeleteDaemonSetForeground(d.client, metav1.NamespaceSystem, dsName); err != nil {
|
||||||
return fmt.Errorf("unable to cleanup the DaemonSet used for prepulling %s: %v", component, err)
|
return errors.Wrapf(err, "unable to cleanup the DaemonSet used for prepulling %s", component)
|
||||||
}
|
}
|
||||||
fmt.Printf("[upgrade/prepull] Prepulled image for component %s.\n", component)
|
fmt.Printf("[upgrade/prepull] Prepulled image for component %s.\n", component)
|
||||||
return nil
|
return nil
|
||||||
@@ -130,7 +132,7 @@ func waitForItemsFromChan(timeoutChan <-chan time.Time, stringChan chan string,
|
|||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-timeoutChan:
|
case <-timeoutChan:
|
||||||
return fmt.Errorf("The prepull operation timed out")
|
return errors.New("The prepull operation timed out")
|
||||||
case result := <-stringChan:
|
case result := <-stringChan:
|
||||||
i++
|
i++
|
||||||
// If the cleanup function errors; error here as well
|
// If the cleanup function errors; error here as well
|
||||||
|
@@ -17,10 +17,11 @@ limitations under the License.
|
|||||||
package upgrade
|
package upgrade
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||||
//"k8s.io/apimachinery/pkg/util/version"
|
//"k8s.io/apimachinery/pkg/util/version"
|
||||||
)
|
)
|
||||||
@@ -34,7 +35,7 @@ func NewFailedCreatePrepuller() Prepuller {
|
|||||||
|
|
||||||
func (p *failedCreatePrepuller) CreateFunc(component string) error {
|
func (p *failedCreatePrepuller) CreateFunc(component string) error {
|
||||||
if component == "kube-controller-manager" {
|
if component == "kube-controller-manager" {
|
||||||
return fmt.Errorf("boo")
|
return errors.New("boo")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -79,7 +80,7 @@ func (p *failedDeletePrepuller) WaitFunc(component string) {}
|
|||||||
|
|
||||||
func (p *failedDeletePrepuller) DeleteFunc(component string) error {
|
func (p *failedDeletePrepuller) DeleteFunc(component string) error {
|
||||||
if component == "kube-scheduler" {
|
if component == "kube-scheduler" {
|
||||||
return fmt.Errorf("boo")
|
return errors.New("boo")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@@ -20,6 +20,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
apps "k8s.io/api/apps/v1"
|
apps "k8s.io/api/apps/v1"
|
||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
@@ -120,7 +122,7 @@ func SelfHostedControlPlane(client clientset.Interface, waiter apiclient.Waiter,
|
|||||||
if err := apiclient.TryRunCommand(func() error {
|
if err := apiclient.TryRunCommand(func() error {
|
||||||
|
|
||||||
if _, err := client.AppsV1().DaemonSets(newDS.ObjectMeta.Namespace).Update(newDS); err != nil {
|
if _, err := client.AppsV1().DaemonSets(newDS.ObjectMeta.Namespace).Update(newDS); err != nil {
|
||||||
return fmt.Errorf("couldn't update self-hosted component's DaemonSet: %v", err)
|
return errors.Wrapf(err, "couldn't update self-hosted component's DaemonSet")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}, selfHostingFailureThreshold); err != nil {
|
}, selfHostingFailureThreshold); err != nil {
|
||||||
@@ -248,7 +250,7 @@ func getCurrentControlPlaneComponentResources(client clientset.Interface) (map[s
|
|||||||
|
|
||||||
// Make sure that there are only one Pod with this label selector; otherwise unexpected things can happen
|
// Make sure that there are only one Pod with this label selector; otherwise unexpected things can happen
|
||||||
if len(podList.Items) > 1 {
|
if len(podList.Items) > 1 {
|
||||||
return nil, fmt.Errorf("too many pods with label selector %q found in the %s namespace", podLabelSelector, metav1.NamespaceSystem)
|
return nil, errors.Errorf("too many pods with label selector %q found in the %s namespace", podLabelSelector, metav1.NamespaceSystem)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the component's DaemonSet object
|
// Get the component's DaemonSet object
|
||||||
|
@@ -190,7 +190,7 @@ func upgradeComponent(component string, waiter apiclient.Waiter, pathMgr StaticP
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err := renewCerts(cfg, component); err != nil {
|
if err := renewCerts(cfg, component); err != nil {
|
||||||
return fmt.Errorf("failed to renew certificates for component %q: %v", component, err)
|
return errors.Wrapf(err, "failed to renew certificates for component %q", component)
|
||||||
}
|
}
|
||||||
|
|
||||||
// The old manifest is here; in the /etc/kubernetes/manifests/
|
// The old manifest is here; in the /etc/kubernetes/manifests/
|
||||||
@@ -290,12 +290,12 @@ func performEtcdStaticPodUpgrade(client clientset.Interface, waiter apiclient.Wa
|
|||||||
|
|
||||||
currentEtcdVersion, err := version.ParseSemantic(currentEtcdVersionStr)
|
currentEtcdVersion, err := version.ParseSemantic(currentEtcdVersionStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return true, fmt.Errorf("failed to parse the current etcd version(%s): %v", currentEtcdVersionStr, err)
|
return true, errors.Wrapf(err, "failed to parse the current etcd version(%s)", currentEtcdVersionStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comparing current etcd version with desired to catch the same version or downgrade condition and fail on them.
|
// Comparing current etcd version with desired to catch the same version or downgrade condition and fail on them.
|
||||||
if desiredEtcdVersion.LessThan(currentEtcdVersion) {
|
if desiredEtcdVersion.LessThan(currentEtcdVersion) {
|
||||||
return false, fmt.Errorf("the desired etcd version for this Kubernetes version %q is %q, but the current etcd version is %q. Won't downgrade etcd, instead just continue", cfg.KubernetesVersion, desiredEtcdVersion.String(), currentEtcdVersion.String())
|
return false, errors.Errorf("the desired etcd version for this Kubernetes version %q is %q, but the current etcd version is %q. Won't downgrade etcd, instead just continue", cfg.KubernetesVersion, desiredEtcdVersion.String(), currentEtcdVersion.String())
|
||||||
}
|
}
|
||||||
// For the case when desired etcd version is the same as current etcd version
|
// For the case when desired etcd version is the same as current etcd version
|
||||||
if strings.Compare(desiredEtcdVersion.String(), currentEtcdVersion.String()) == 0 {
|
if strings.Compare(desiredEtcdVersion.String(), currentEtcdVersion.String()) == 0 {
|
||||||
@@ -339,7 +339,7 @@ func performEtcdStaticPodUpgrade(client clientset.Interface, waiter apiclient.Wa
|
|||||||
fmt.Println("[upgrade/etcd] Rolling back etcd data")
|
fmt.Println("[upgrade/etcd] Rolling back etcd data")
|
||||||
if err := rollbackEtcdData(cfg, pathMgr); err != nil {
|
if err := rollbackEtcdData(cfg, pathMgr); err != nil {
|
||||||
// Even copying back datastore failed, no options for recovery left, bailing out
|
// Even copying back datastore failed, no options for recovery left, bailing out
|
||||||
return true, fmt.Errorf("fatal error rolling back local etcd cluster datadir: %v, the backup of etcd database is stored here:(%s)", err, backupEtcdDir)
|
return true, errors.Errorf("fatal error rolling back local etcd cluster datadir: %v, the backup of etcd database is stored here:(%s)", err, backupEtcdDir)
|
||||||
}
|
}
|
||||||
fmt.Println("[upgrade/etcd] Etcd data rollback successful")
|
fmt.Println("[upgrade/etcd] Etcd data rollback successful")
|
||||||
|
|
||||||
@@ -348,7 +348,7 @@ func performEtcdStaticPodUpgrade(client clientset.Interface, waiter apiclient.Wa
|
|||||||
if _, err := oldEtcdClient.WaitForClusterAvailable(noDelay, retries, retryInterval); err != nil {
|
if _, err := oldEtcdClient.WaitForClusterAvailable(noDelay, retries, retryInterval); err != nil {
|
||||||
fmt.Printf("[upgrade/etcd] Failed to healthcheck previous etcd: %v\n", err)
|
fmt.Printf("[upgrade/etcd] Failed to healthcheck previous etcd: %v\n", err)
|
||||||
// Nothing else left to try to recover etcd cluster
|
// Nothing else left to try to recover etcd cluster
|
||||||
return true, fmt.Errorf("fatal error rolling back local etcd cluster manifest: %v, the backup of etcd database is stored here:(%s)", err, backupEtcdDir)
|
return true, errors.Wrapf(err, "fatal error rolling back local etcd cluster manifest, the backup of etcd database is stored here:(%s)", backupEtcdDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
// We've recovered to the previous etcd from this case
|
// We've recovered to the previous etcd from this case
|
||||||
@@ -377,7 +377,7 @@ func performEtcdStaticPodUpgrade(client clientset.Interface, waiter apiclient.Wa
|
|||||||
fmt.Println("[upgrade/etcd] Rolling back etcd data")
|
fmt.Println("[upgrade/etcd] Rolling back etcd data")
|
||||||
if err := rollbackEtcdData(cfg, pathMgr); err != nil {
|
if err := rollbackEtcdData(cfg, pathMgr); err != nil {
|
||||||
// Even copying back datastore failed, no options for recovery left, bailing out
|
// Even copying back datastore failed, no options for recovery left, bailing out
|
||||||
return true, fmt.Errorf("fatal error rolling back local etcd cluster datadir: %v, the backup of etcd database is stored here:(%s)", err, backupEtcdDir)
|
return true, errors.Wrapf(err, "fatal error rolling back local etcd cluster datadir, the backup of etcd database is stored here:(%s)", backupEtcdDir)
|
||||||
}
|
}
|
||||||
fmt.Println("[upgrade/etcd] Etcd data rollback successful")
|
fmt.Println("[upgrade/etcd] Etcd data rollback successful")
|
||||||
|
|
||||||
@@ -391,7 +391,7 @@ func performEtcdStaticPodUpgrade(client clientset.Interface, waiter apiclient.Wa
|
|||||||
if _, err := oldEtcdClient.WaitForClusterAvailable(noDelay, retries, retryInterval); err != nil {
|
if _, err := oldEtcdClient.WaitForClusterAvailable(noDelay, retries, retryInterval); err != nil {
|
||||||
fmt.Printf("[upgrade/etcd] Failed to healthcheck previous etcd: %v\n", err)
|
fmt.Printf("[upgrade/etcd] Failed to healthcheck previous etcd: %v\n", err)
|
||||||
// Nothing else left to try to recover etcd cluster
|
// Nothing else left to try to recover etcd cluster
|
||||||
return true, fmt.Errorf("fatal error rolling back local etcd cluster manifest: %v, the backup of etcd database is stored here:(%s)", err, backupEtcdDir)
|
return true, errors.Wrapf(err, "fatal error rolling back local etcd cluster manifest, the backup of etcd database is stored here:(%s)", backupEtcdDir)
|
||||||
}
|
}
|
||||||
fmt.Println("[upgrade/etcd] Etcd was rolled back and is now available")
|
fmt.Println("[upgrade/etcd] Etcd was rolled back and is now available")
|
||||||
|
|
||||||
@@ -510,7 +510,7 @@ func rollbackEtcdData(cfg *kubeadmapi.InitConfiguration, pathMgr StaticPodPathMa
|
|||||||
|
|
||||||
if err := util.CopyDir(backupEtcdDir, runningEtcdDir); err != nil {
|
if err := util.CopyDir(backupEtcdDir, runningEtcdDir); err != nil {
|
||||||
// Let the user know there we're problems, but we tried to reçover
|
// Let the user know there we're problems, but we tried to reçover
|
||||||
return fmt.Errorf("couldn't recover etcd database with error: %v, the location of etcd backup: %s ", err, backupEtcdDir)
|
return errors.Wrapf(err, "couldn't recover etcd database with error, the location of etcd backup: %s ", backupEtcdDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -522,7 +522,7 @@ func renewCerts(cfg *kubeadmapi.InitConfiguration, component string) error {
|
|||||||
if component == constants.Etcd || component == constants.KubeAPIServer {
|
if component == constants.Etcd || component == constants.KubeAPIServer {
|
||||||
caCert, caKey, err := certsphase.LoadCertificateAuthority(cfg.CertificatesDir, certsphase.KubeadmCertEtcdCA.BaseName)
|
caCert, caKey, err := certsphase.LoadCertificateAuthority(cfg.CertificatesDir, certsphase.KubeadmCertEtcdCA.BaseName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to upgrade the %s CA certificate and key: %v", constants.Etcd, err)
|
return errors.Wrapf(err, "failed to upgrade the %s CA certificate and key", constants.Etcd)
|
||||||
}
|
}
|
||||||
renewer := renewal.NewFileRenewal(caCert, caKey)
|
renewer := renewal.NewFileRenewal(caCert, caKey)
|
||||||
|
|
||||||
@@ -533,14 +533,14 @@ func renewCerts(cfg *kubeadmapi.InitConfiguration, component string) error {
|
|||||||
&certsphase.KubeadmCertEtcdHealthcheck,
|
&certsphase.KubeadmCertEtcdHealthcheck,
|
||||||
} {
|
} {
|
||||||
if err := renewal.RenewExistingCert(cfg.CertificatesDir, cert.BaseName, renewer); err != nil {
|
if err := renewal.RenewExistingCert(cfg.CertificatesDir, cert.BaseName, renewer); err != nil {
|
||||||
return fmt.Errorf("failed to renew %s certificate and key: %v", cert.Name, err)
|
return errors.Wrapf(err, "failed to renew %s certificate and key", cert.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if component == constants.KubeAPIServer {
|
if component == constants.KubeAPIServer {
|
||||||
cert := certsphase.KubeadmCertEtcdAPIClient
|
cert := certsphase.KubeadmCertEtcdAPIClient
|
||||||
if err := renewal.RenewExistingCert(cfg.CertificatesDir, cert.BaseName, renewer); err != nil {
|
if err := renewal.RenewExistingCert(cfg.CertificatesDir, cert.BaseName, renewer); err != nil {
|
||||||
return fmt.Errorf("failed to renew %s certificate and key: %v", cert.Name, err)
|
return errors.Wrapf(err, "failed to renew %s certificate and key", cert.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -29,6 +29,8 @@ import (
|
|||||||
|
|
||||||
"github.com/coreos/etcd/clientv3"
|
"github.com/coreos/etcd/clientv3"
|
||||||
"github.com/coreos/etcd/pkg/transport"
|
"github.com/coreos/etcd/pkg/transport"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation"
|
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||||
@@ -144,22 +146,22 @@ type fakeStaticPodPathManager struct {
|
|||||||
func NewFakeStaticPodPathManager(moveFileFunc func(string, string) error) (StaticPodPathManager, error) {
|
func NewFakeStaticPodPathManager(moveFileFunc func(string, string) error) (StaticPodPathManager, error) {
|
||||||
kubernetesDir, err := ioutil.TempDir("", "kubeadm-pathmanager-")
|
kubernetesDir, err := ioutil.TempDir("", "kubeadm-pathmanager-")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("couldn't create a temporary directory for the upgrade: %v", err)
|
return nil, errors.Wrapf(err, "couldn't create a temporary directory for the upgrade")
|
||||||
}
|
}
|
||||||
|
|
||||||
realManifestDir := filepath.Join(kubernetesDir, constants.ManifestsSubDirName)
|
realManifestDir := filepath.Join(kubernetesDir, constants.ManifestsSubDirName)
|
||||||
if err := os.Mkdir(realManifestDir, 0700); err != nil {
|
if err := os.Mkdir(realManifestDir, 0700); err != nil {
|
||||||
return nil, fmt.Errorf("couldn't create a realManifestDir for the upgrade: %v", err)
|
return nil, errors.Wrapf(err, "couldn't create a realManifestDir for the upgrade")
|
||||||
}
|
}
|
||||||
|
|
||||||
upgradedManifestDir := filepath.Join(kubernetesDir, "upgraded-manifests")
|
upgradedManifestDir := filepath.Join(kubernetesDir, "upgraded-manifests")
|
||||||
if err := os.Mkdir(upgradedManifestDir, 0700); err != nil {
|
if err := os.Mkdir(upgradedManifestDir, 0700); err != nil {
|
||||||
return nil, fmt.Errorf("couldn't create a upgradedManifestDir for the upgrade: %v", err)
|
return nil, errors.Wrapf(err, "couldn't create a upgradedManifestDir for the upgrade")
|
||||||
}
|
}
|
||||||
|
|
||||||
backupManifestDir := filepath.Join(kubernetesDir, "backup-manifests")
|
backupManifestDir := filepath.Join(kubernetesDir, "backup-manifests")
|
||||||
if err := os.Mkdir(backupManifestDir, 0700); err != nil {
|
if err := os.Mkdir(backupManifestDir, 0700); err != nil {
|
||||||
return nil, fmt.Errorf("couldn't create a backupManifestDir for the upgrade: %v", err)
|
return nil, errors.Wrap(err, "couldn't create a backupManifestDir for the upgrade")
|
||||||
}
|
}
|
||||||
|
|
||||||
backupEtcdDir := filepath.Join(kubernetesDir, "kubeadm-backup-etcd")
|
backupEtcdDir := filepath.Join(kubernetesDir, "kubeadm-backup-etcd")
|
||||||
@@ -325,7 +327,7 @@ func TestStaticPodControlPlane(t *testing.T) {
|
|||||||
{
|
{
|
||||||
description: "any wait error should result in a rollback and an abort",
|
description: "any wait error should result in a rollback and an abort",
|
||||||
waitErrsToReturn: map[string]error{
|
waitErrsToReturn: map[string]error{
|
||||||
waitForHashes: fmt.Errorf("boo! failed"),
|
waitForHashes: errors.New("boo! failed"),
|
||||||
waitForHashChange: nil,
|
waitForHashChange: nil,
|
||||||
waitForPodsWithLabel: nil,
|
waitForPodsWithLabel: nil,
|
||||||
},
|
},
|
||||||
@@ -339,7 +341,7 @@ func TestStaticPodControlPlane(t *testing.T) {
|
|||||||
description: "any wait error should result in a rollback and an abort",
|
description: "any wait error should result in a rollback and an abort",
|
||||||
waitErrsToReturn: map[string]error{
|
waitErrsToReturn: map[string]error{
|
||||||
waitForHashes: nil,
|
waitForHashes: nil,
|
||||||
waitForHashChange: fmt.Errorf("boo! failed"),
|
waitForHashChange: errors.New("boo! failed"),
|
||||||
waitForPodsWithLabel: nil,
|
waitForPodsWithLabel: nil,
|
||||||
},
|
},
|
||||||
moveFileFunc: func(oldPath, newPath string) error {
|
moveFileFunc: func(oldPath, newPath string) error {
|
||||||
@@ -353,7 +355,7 @@ func TestStaticPodControlPlane(t *testing.T) {
|
|||||||
waitErrsToReturn: map[string]error{
|
waitErrsToReturn: map[string]error{
|
||||||
waitForHashes: nil,
|
waitForHashes: nil,
|
||||||
waitForHashChange: nil,
|
waitForHashChange: nil,
|
||||||
waitForPodsWithLabel: fmt.Errorf("boo! failed"),
|
waitForPodsWithLabel: errors.New("boo! failed"),
|
||||||
},
|
},
|
||||||
moveFileFunc: func(oldPath, newPath string) error {
|
moveFileFunc: func(oldPath, newPath string) error {
|
||||||
return os.Rename(oldPath, newPath)
|
return os.Rename(oldPath, newPath)
|
||||||
@@ -371,7 +373,7 @@ func TestStaticPodControlPlane(t *testing.T) {
|
|||||||
moveFileFunc: func(oldPath, newPath string) error {
|
moveFileFunc: func(oldPath, newPath string) error {
|
||||||
// fail for kube-apiserver move
|
// fail for kube-apiserver move
|
||||||
if strings.Contains(newPath, "kube-apiserver") {
|
if strings.Contains(newPath, "kube-apiserver") {
|
||||||
return fmt.Errorf("moving the kube-apiserver file failed")
|
return errors.New("moving the kube-apiserver file failed")
|
||||||
}
|
}
|
||||||
return os.Rename(oldPath, newPath)
|
return os.Rename(oldPath, newPath)
|
||||||
},
|
},
|
||||||
@@ -388,7 +390,7 @@ func TestStaticPodControlPlane(t *testing.T) {
|
|||||||
moveFileFunc: func(oldPath, newPath string) error {
|
moveFileFunc: func(oldPath, newPath string) error {
|
||||||
// fail for kube-controller-manager move
|
// fail for kube-controller-manager move
|
||||||
if strings.Contains(newPath, "kube-controller-manager") {
|
if strings.Contains(newPath, "kube-controller-manager") {
|
||||||
return fmt.Errorf("moving the kube-apiserver file failed")
|
return errors.New("moving the kube-apiserver file failed")
|
||||||
}
|
}
|
||||||
return os.Rename(oldPath, newPath)
|
return os.Rename(oldPath, newPath)
|
||||||
},
|
},
|
||||||
@@ -405,7 +407,7 @@ func TestStaticPodControlPlane(t *testing.T) {
|
|||||||
moveFileFunc: func(oldPath, newPath string) error {
|
moveFileFunc: func(oldPath, newPath string) error {
|
||||||
// fail for kube-scheduler move
|
// fail for kube-scheduler move
|
||||||
if strings.Contains(newPath, "kube-scheduler") {
|
if strings.Contains(newPath, "kube-scheduler") {
|
||||||
return fmt.Errorf("moving the kube-apiserver file failed")
|
return errors.New("moving the kube-apiserver file failed")
|
||||||
}
|
}
|
||||||
return os.Rename(oldPath, newPath)
|
return os.Rename(oldPath, newPath)
|
||||||
},
|
},
|
||||||
|
@@ -88,7 +88,7 @@ func (g *KubeVersionGetter) KubeadmVersion() (string, *versionutil.Version, erro
|
|||||||
func (g *KubeVersionGetter) VersionFromCILabel(ciVersionLabel, description string) (string, *versionutil.Version, error) {
|
func (g *KubeVersionGetter) VersionFromCILabel(ciVersionLabel, description string) (string, *versionutil.Version, error) {
|
||||||
versionStr, err := kubeadmutil.KubernetesReleaseVersion(ciVersionLabel)
|
versionStr, err := kubeadmutil.KubernetesReleaseVersion(ciVersionLabel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, fmt.Errorf("Couldn't fetch latest %s from the internet: %v", description, err)
|
return "", nil, errors.Wrapf(err, "Couldn't fetch latest %s from the internet", description)
|
||||||
}
|
}
|
||||||
|
|
||||||
if description != "" {
|
if description != "" {
|
||||||
@@ -97,7 +97,7 @@ func (g *KubeVersionGetter) VersionFromCILabel(ciVersionLabel, description strin
|
|||||||
|
|
||||||
ver, err := versionutil.ParseSemantic(versionStr)
|
ver, err := versionutil.ParseSemantic(versionStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, fmt.Errorf("Couldn't parse latest %s: %v", description, err)
|
return "", nil, errors.Wrapf(err, "Couldn't parse latest %s", description)
|
||||||
}
|
}
|
||||||
return versionStr, ver, nil
|
return versionStr, ver, nil
|
||||||
}
|
}
|
||||||
@@ -147,7 +147,7 @@ func (o *OfflineVersionGetter) VersionFromCILabel(ciVersionLabel, description st
|
|||||||
}
|
}
|
||||||
ver, err := versionutil.ParseSemantic(o.version)
|
ver, err := versionutil.ParseSemantic(o.version)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, fmt.Errorf("Couldn't parse version %s: %v", description, err)
|
return "", nil, errors.Wrapf(err, "Couldn't parse version %s", description)
|
||||||
}
|
}
|
||||||
return o.version, ver, nil
|
return o.version, ver, nil
|
||||||
}
|
}
|
||||||
|
@@ -17,10 +17,11 @@ limitations under the License.
|
|||||||
package apiclient
|
package apiclient
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
@@ -88,12 +89,12 @@ func (idr *InitDryRunGetter) handleKubernetesService(action core.GetAction) (boo
|
|||||||
|
|
||||||
_, svcSubnet, err := net.ParseCIDR(idr.serviceSubnet)
|
_, svcSubnet, err := net.ParseCIDR(idr.serviceSubnet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return true, nil, fmt.Errorf("error parsing CIDR %q: %v", idr.serviceSubnet, err)
|
return true, nil, errors.Wrapf(err, "error parsing CIDR %q", idr.serviceSubnet)
|
||||||
}
|
}
|
||||||
|
|
||||||
internalAPIServerVirtualIP, err := ipallocator.GetIndexedIP(svcSubnet, 1)
|
internalAPIServerVirtualIP, err := ipallocator.GetIndexedIP(svcSubnet, 1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return true, nil, fmt.Errorf("unable to get first IP address from the given CIDR (%s): %v", svcSubnet.String(), err)
|
return true, nil, errors.Wrapf(err, "unable to get first IP address from the given CIDR (%s)", svcSubnet.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
// The only used field of this Service object is the ClusterIP, which kube-dns uses to calculate its own IP
|
// The only used field of this Service object is the ClusterIP, which kube-dns uses to calculate its own IP
|
||||||
|
@@ -17,11 +17,12 @@ limitations under the License.
|
|||||||
package audit
|
package audit
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||||
@@ -49,7 +50,7 @@ func CreateDefaultAuditLogPolicy(policyFile string) error {
|
|||||||
func writePolicyToDisk(policyFile string, policy *auditv1.Policy) error {
|
func writePolicyToDisk(policyFile string, policy *auditv1.Policy) error {
|
||||||
// creates target folder if not already exists
|
// creates target folder if not already exists
|
||||||
if err := os.MkdirAll(filepath.Dir(policyFile), 0700); err != nil {
|
if err := os.MkdirAll(filepath.Dir(policyFile), 0700); err != nil {
|
||||||
return fmt.Errorf("failed to create directory %q: %v", filepath.Dir(policyFile), err)
|
return errors.Wrapf(err, "failed to create directory %q: ", filepath.Dir(policyFile))
|
||||||
}
|
}
|
||||||
|
|
||||||
scheme := runtime.NewScheme()
|
scheme := runtime.NewScheme()
|
||||||
@@ -62,11 +63,11 @@ func writePolicyToDisk(policyFile string, policy *auditv1.Policy) error {
|
|||||||
serialized, err := util.MarshalToYamlForCodecs(policy, auditv1.SchemeGroupVersion, codecs)
|
serialized, err := util.MarshalToYamlForCodecs(policy, auditv1.SchemeGroupVersion, codecs)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to marshal audit policy to YAML: %v", err)
|
return errors.Wrap(err, "failed to marshal audit policy to YAML")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := ioutil.WriteFile(policyFile, serialized, 0600); err != nil {
|
if err := ioutil.WriteFile(policyFile, serialized, 0600); err != nil {
|
||||||
return fmt.Errorf("failed to write audit policy to %v: %v", policyFile, err)
|
return errors.Wrapf(err, "failed to write audit policy to %v: ", policyFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@@ -17,7 +17,6 @@ limitations under the License.
|
|||||||
package util
|
package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
@@ -41,7 +40,7 @@ func GetCgroupDriverDocker(execer utilsexec.Interface) (string, error) {
|
|||||||
|
|
||||||
func validateCgroupDriver(driver string) error {
|
func validateCgroupDriver(driver string) error {
|
||||||
if driver != "cgroupfs" && driver != "systemd" {
|
if driver != "cgroupfs" && driver != "systemd" {
|
||||||
return fmt.Errorf("unknown cgroup driver %q", driver)
|
return errors.Errorf("unknown cgroup driver %q", driver)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@@ -19,7 +19,7 @@ limitations under the License.
|
|||||||
package util
|
package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"github.com/pkg/errors"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"syscall"
|
"syscall"
|
||||||
@@ -30,11 +30,11 @@ import (
|
|||||||
// `rootfs`
|
// `rootfs`
|
||||||
func Chroot(rootfs string) error {
|
func Chroot(rootfs string) error {
|
||||||
if err := syscall.Chroot(rootfs); err != nil {
|
if err := syscall.Chroot(rootfs); err != nil {
|
||||||
return fmt.Errorf("unable to chroot to %s: %v", rootfs, err)
|
return errors.Wrapf(err, "unable to chroot to %s", rootfs)
|
||||||
}
|
}
|
||||||
root := filepath.FromSlash("/")
|
root := filepath.FromSlash("/")
|
||||||
if err := os.Chdir(root); err != nil {
|
if err := os.Chdir(root); err != nil {
|
||||||
return fmt.Errorf("unable to chdir to %s: %v", root, err)
|
return errors.Wrapf(err, "unable to chdir to %s", root)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@@ -19,12 +19,12 @@ limitations under the License.
|
|||||||
package util
|
package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Chroot chroot()s to the new path.
|
// Chroot chroot()s to the new path.
|
||||||
// NB: All file paths after this call are effectively relative to
|
// NB: All file paths after this call are effectively relative to
|
||||||
// `rootfs`
|
// `rootfs`
|
||||||
func Chroot(rootfs string) error {
|
func Chroot(rootfs string) error {
|
||||||
return fmt.Errorf("chroot is not implemented on Windows")
|
return errors.New("chroot is not implemented on Windows")
|
||||||
}
|
}
|
||||||
|
@@ -25,7 +25,9 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/util/version"
|
"k8s.io/apimachinery/pkg/util/version"
|
||||||
@@ -100,7 +102,7 @@ func getInitConfigurationFromCluster(kubeconfigDir string, client clientset.Inte
|
|||||||
// gets ClusterConfiguration from kubeadm-config
|
// gets ClusterConfiguration from kubeadm-config
|
||||||
clusterConfigurationData, ok := configMap.Data[constants.ClusterConfigurationConfigMapKey]
|
clusterConfigurationData, ok := configMap.Data[constants.ClusterConfigurationConfigMapKey]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("unexpected error when reading kubeadm-config ConfigMap: %s key value pair missing", constants.ClusterConfigurationConfigMapKey)
|
return nil, errors.Errorf("unexpected error when reading kubeadm-config ConfigMap: %s key value pair missing", constants.ClusterConfigurationConfigMapKey)
|
||||||
}
|
}
|
||||||
if err := runtime.DecodeInto(kubeadmscheme.Codecs.UniversalDecoder(), []byte(clusterConfigurationData), &initcfg.ClusterConfiguration); err != nil {
|
if err := runtime.DecodeInto(kubeadmscheme.Codecs.UniversalDecoder(), []byte(clusterConfigurationData), &initcfg.ClusterConfiguration); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -143,7 +145,7 @@ func getNodeRegistration(kubeconfigDir string, client clientset.Interface, nodeR
|
|||||||
|
|
||||||
criSocket, ok := node.ObjectMeta.Annotations[constants.AnnotationKubeadmCRISocket]
|
criSocket, ok := node.ObjectMeta.Annotations[constants.AnnotationKubeadmCRISocket]
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("Node %s doesn't have %s annotation", nodeName, constants.AnnotationKubeadmCRISocket)
|
return errors.Errorf("node %s doesn't have %s annotation", nodeName, constants.AnnotationKubeadmCRISocket)
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns the nodeRegistration attributes
|
// returns the nodeRegistration attributes
|
||||||
@@ -183,7 +185,7 @@ func getNodeNameFromKubeletConfig(kubeconfigDir string) (string, error) {
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return "", errors.New("Invalid kubelet.conf. X509 certificate expected")
|
return "", errors.New("invalid kubelet.conf. X509 certificate expected")
|
||||||
}
|
}
|
||||||
|
|
||||||
// We are only putting one certificate in the certificate pem file, so it's safe to just pick the first one
|
// We are only putting one certificate in the certificate pem file, so it's safe to just pick the first one
|
||||||
@@ -224,7 +226,7 @@ func getComponentConfigs(client clientset.Interface, clusterConfiguration *kubea
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ok := registration.SetToInternalConfig(obj, clusterConfiguration); !ok {
|
if ok := registration.SetToInternalConfig(obj, clusterConfiguration); !ok {
|
||||||
return fmt.Errorf("couldn't save componentconfig value for kind %q", string(kind))
|
return errors.Errorf("couldn't save componentconfig value for kind %q", string(kind))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@@ -17,12 +17,12 @@ limitations under the License.
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
netutil "k8s.io/apimachinery/pkg/util/net"
|
netutil "k8s.io/apimachinery/pkg/util/net"
|
||||||
@@ -53,7 +53,7 @@ func AnyConfigFileAndDefaultsToInternal(cfgPath string) (runtime.Object, error)
|
|||||||
if kubeadmutil.GroupVersionKindsHasJoinConfiguration(gvks...) {
|
if kubeadmutil.GroupVersionKindsHasJoinConfiguration(gvks...) {
|
||||||
return JoinConfigFileAndDefaultsToInternalConfig(cfgPath, &kubeadmapiv1beta1.JoinConfiguration{})
|
return JoinConfigFileAndDefaultsToInternalConfig(cfgPath, &kubeadmapiv1beta1.JoinConfiguration{})
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("didn't recognize types with GroupVersionKind: %v", gvks)
|
return nil, errors.Errorf("didn't recognize types with GroupVersionKind: %v", gvks)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarshalKubeadmConfigObject marshals an Object registered in the kubeadm scheme. If the object is a InitConfiguration or ClusterConfiguration, some extra logic is run
|
// MarshalKubeadmConfigObject marshals an Object registered in the kubeadm scheme. If the object is a InitConfiguration or ClusterConfiguration, some extra logic is run
|
||||||
@@ -89,7 +89,7 @@ func DetectUnsupportedVersion(b []byte) error {
|
|||||||
knownKinds := map[string]bool{}
|
knownKinds := map[string]bool{}
|
||||||
for _, gvk := range gvks {
|
for _, gvk := range gvks {
|
||||||
if useKubeadmVersion := oldKnownAPIVersions[gvk.GroupVersion().String()]; len(useKubeadmVersion) != 0 {
|
if useKubeadmVersion := oldKnownAPIVersions[gvk.GroupVersion().String()]; len(useKubeadmVersion) != 0 {
|
||||||
return fmt.Errorf("your configuration file uses an old API spec: %q. Please use kubeadm %s instead and run 'kubeadm config migrate --old-config old.yaml --new-config new.yaml', which will write the new, similar spec using a newer API version.", gvk.GroupVersion().String(), useKubeadmVersion)
|
return errors.Errorf("your configuration file uses an old API spec: %q. Please use kubeadm %s instead and run 'kubeadm config migrate --old-config old.yaml --new-config new.yaml', which will write the new, similar spec using a newer API version.", gvk.GroupVersion().String(), useKubeadmVersion)
|
||||||
}
|
}
|
||||||
knownKinds[gvk.Kind] = true
|
knownKinds[gvk.Kind] = true
|
||||||
}
|
}
|
||||||
@@ -128,10 +128,10 @@ func NormalizeKubernetesVersion(cfg *kubeadmapi.ClusterConfiguration) error {
|
|||||||
// Parse the given kubernetes version and make sure it's higher than the lowest supported
|
// Parse the given kubernetes version and make sure it's higher than the lowest supported
|
||||||
k8sVersion, err := version.ParseSemantic(cfg.KubernetesVersion)
|
k8sVersion, err := version.ParseSemantic(cfg.KubernetesVersion)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("couldn't parse kubernetes version %q: %v", cfg.KubernetesVersion, err)
|
return errors.Wrapf(err, "couldn't parse kubernetes version %q", cfg.KubernetesVersion)
|
||||||
}
|
}
|
||||||
if k8sVersion.LessThan(constants.MinimumControlPlaneVersion) {
|
if k8sVersion.LessThan(constants.MinimumControlPlaneVersion) {
|
||||||
return fmt.Errorf("this version of kubeadm only supports deploying clusters with the control plane version >= %s. Current version: %s", constants.MinimumControlPlaneVersion.String(), cfg.KubernetesVersion)
|
return errors.Errorf("this version of kubeadm only supports deploying clusters with the control plane version >= %s. Current version: %s", constants.MinimumControlPlaneVersion.String(), cfg.KubernetesVersion)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -152,10 +152,10 @@ func LowercaseSANs(sans []string) {
|
|||||||
func VerifyAPIServerBindAddress(address string) error {
|
func VerifyAPIServerBindAddress(address string) error {
|
||||||
ip := net.ParseIP(address)
|
ip := net.ParseIP(address)
|
||||||
if ip == nil {
|
if ip == nil {
|
||||||
return fmt.Errorf("cannot parse IP address: %s", address)
|
return errors.Errorf("cannot parse IP address: %s", address)
|
||||||
}
|
}
|
||||||
if !ip.IsGlobalUnicast() {
|
if !ip.IsGlobalUnicast() {
|
||||||
return fmt.Errorf("cannot use %q as the bind address for the API Server", address)
|
return errors.Errorf("cannot use %q as the bind address for the API Server", address)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -169,7 +169,7 @@ func ChooseAPIServerBindAddress(bindAddress net.IP) (net.IP, error) {
|
|||||||
glog.Warningf("WARNING: could not obtain a bind address for the API Server: %v; using: %s", err, constants.DefaultAPIServerBindAddress)
|
glog.Warningf("WARNING: could not obtain a bind address for the API Server: %v; using: %s", err, constants.DefaultAPIServerBindAddress)
|
||||||
defaultIP := net.ParseIP(constants.DefaultAPIServerBindAddress)
|
defaultIP := net.ParseIP(constants.DefaultAPIServerBindAddress)
|
||||||
if defaultIP == nil {
|
if defaultIP == nil {
|
||||||
return nil, fmt.Errorf("cannot parse default IP address: %s", constants.DefaultAPIServerBindAddress)
|
return nil, errors.Errorf("cannot parse default IP address: %s", constants.DefaultAPIServerBindAddress)
|
||||||
}
|
}
|
||||||
return defaultIP, nil
|
return defaultIP, nil
|
||||||
}
|
}
|
||||||
|
@@ -26,6 +26,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
@@ -72,7 +73,7 @@ func SetBootstrapTokensDynamicDefaults(cfg *[]kubeadmapi.BootstrapToken) error {
|
|||||||
|
|
||||||
tokenStr, err := bootstraputil.GenerateBootstrapToken()
|
tokenStr, err := bootstraputil.GenerateBootstrapToken()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("couldn't generate random token: %v", err)
|
return errors.Wrap(err, "couldn't generate random token")
|
||||||
}
|
}
|
||||||
token, err := kubeadmapi.NewBootstrapTokenString(tokenStr)
|
token, err := kubeadmapi.NewBootstrapTokenString(tokenStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -105,7 +106,7 @@ func SetAPIEndpointDynamicDefaults(cfg *kubeadmapi.APIEndpoint) error {
|
|||||||
// validate cfg.API.AdvertiseAddress.
|
// validate cfg.API.AdvertiseAddress.
|
||||||
addressIP := net.ParseIP(cfg.AdvertiseAddress)
|
addressIP := net.ParseIP(cfg.AdvertiseAddress)
|
||||||
if addressIP == nil && cfg.AdvertiseAddress != "" {
|
if addressIP == nil && cfg.AdvertiseAddress != "" {
|
||||||
return fmt.Errorf("couldn't use \"%s\" as \"apiserver-advertise-address\", must be ipv4 or ipv6 address", cfg.AdvertiseAddress)
|
return errors.Errorf("couldn't use \"%s\" as \"apiserver-advertise-address\", must be ipv4 or ipv6 address", cfg.AdvertiseAddress)
|
||||||
}
|
}
|
||||||
// This is the same logic as the API Server uses, except that if no interface is found the address is set to 0.0.0.0, which is invalid and cannot be used
|
// This is the same logic as the API Server uses, except that if no interface is found the address is set to 0.0.0.0, which is invalid and cannot be used
|
||||||
// for bootstrapping a cluster.
|
// for bootstrapping a cluster.
|
||||||
@@ -168,7 +169,7 @@ func ConfigFileAndDefaultsToInternalConfig(cfgPath string, defaultversionedcfg *
|
|||||||
|
|
||||||
b, err := ioutil.ReadFile(cfgPath)
|
b, err := ioutil.ReadFile(cfgPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unable to read config from %q [%v]", cfgPath, err)
|
return nil, errors.Wrapf(err, "unable to read config from %q ", cfgPath)
|
||||||
}
|
}
|
||||||
internalcfg, err = BytesToInternalConfig(b)
|
internalcfg, err = BytesToInternalConfig(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -249,7 +250,7 @@ func BytesToInternalConfig(b []byte) (*kubeadmapi.InitConfiguration, error) {
|
|||||||
|
|
||||||
// Enforce that InitConfiguration and/or ClusterConfiguration has to exist among the YAML documents
|
// Enforce that InitConfiguration and/or ClusterConfiguration has to exist among the YAML documents
|
||||||
if initcfg == nil && clustercfg == nil {
|
if initcfg == nil && clustercfg == nil {
|
||||||
return nil, fmt.Errorf("no InitConfiguration or ClusterConfiguration kind was found in the YAML file")
|
return nil, errors.New("no InitConfiguration or ClusterConfiguration kind was found in the YAML file")
|
||||||
}
|
}
|
||||||
|
|
||||||
// If InitConfiguration wasn't given, default it by creating an external struct instance, default it and convert into the internal type
|
// If InitConfiguration wasn't given, default it by creating an external struct instance, default it and convert into the internal type
|
||||||
@@ -270,7 +271,7 @@ func BytesToInternalConfig(b []byte) (*kubeadmapi.InitConfiguration, error) {
|
|||||||
registration, found := componentconfigs.Known[kind]
|
registration, found := componentconfigs.Known[kind]
|
||||||
if found {
|
if found {
|
||||||
if ok := registration.SetToInternalConfig(obj, &initcfg.ClusterConfiguration); !ok {
|
if ok := registration.SetToInternalConfig(obj, &initcfg.ClusterConfiguration); !ok {
|
||||||
return nil, fmt.Errorf("couldn't save componentconfig value for kind %q", string(kind))
|
return nil, errors.Errorf("couldn't save componentconfig value for kind %q", string(kind))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// This should never happen in practice
|
// This should never happen in practice
|
||||||
@@ -334,7 +335,7 @@ func MarshalClusterConfigurationToBytes(clustercfg *kubeadmapi.ClusterConfigurat
|
|||||||
defaultedobj, ok := registration.GetFromInternalConfig(defaultedcfg)
|
defaultedobj, ok := registration.GetFromInternalConfig(defaultedcfg)
|
||||||
// Invalid: The caller asked to not print the componentconfigs if defaulted, but defaultComponentConfigs() wasn't able to create default objects to use for reference
|
// Invalid: The caller asked to not print the componentconfigs if defaulted, but defaultComponentConfigs() wasn't able to create default objects to use for reference
|
||||||
if !ok {
|
if !ok {
|
||||||
return []byte{}, fmt.Errorf("couldn't create a default componentconfig object")
|
return []byte{}, errors.New("couldn't create a default componentconfig object")
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the real ComponentConfig object differs from the default, print it out. If not, there's no need to print it out, so skip it
|
// If the real ComponentConfig object differs from the default, print it out. If not, there's no need to print it out, so skip it
|
||||||
|
@@ -17,17 +17,17 @@ limitations under the License.
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
kubeadmscheme "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/scheme"
|
kubeadmscheme "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/scheme"
|
||||||
kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1"
|
kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation"
|
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation"
|
||||||
|
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ func JoinConfigFileAndDefaultsToInternalConfig(cfgPath string, defaultversionedc
|
|||||||
|
|
||||||
b, err := ioutil.ReadFile(cfgPath)
|
b, err := ioutil.ReadFile(cfgPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unable to read config from %q [%v]", cfgPath, err)
|
return nil, errors.Wrapf(err, "unable to read config from %q ", cfgPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := DetectUnsupportedVersion(b); err != nil {
|
if err := DetectUnsupportedVersion(b); err != nil {
|
||||||
@@ -76,7 +76,7 @@ func JoinConfigFileAndDefaultsToInternalConfig(cfgPath string, defaultversionedc
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(joinBytes) == 0 {
|
if len(joinBytes) == 0 {
|
||||||
return nil, fmt.Errorf("no %s found in config file %q", constants.JoinConfigurationKind, cfgPath)
|
return nil, errors.Errorf("no %s found in config file %q", constants.JoinConfigurationKind, cfgPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := runtime.DecodeInto(kubeadmscheme.Codecs.UniversalDecoder(), joinBytes, internalcfg); err != nil {
|
if err := runtime.DecodeInto(kubeadmscheme.Codecs.UniversalDecoder(), joinBytes, internalcfg); err != nil {
|
||||||
|
@@ -22,6 +22,8 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/util/validation"
|
"k8s.io/apimachinery/pkg/util/validation"
|
||||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
)
|
)
|
||||||
@@ -34,13 +36,13 @@ func GetMasterEndpoint(cfg *kubeadmapi.InitConfiguration) (string, error) {
|
|||||||
// parse the bind port
|
// parse the bind port
|
||||||
bindPortString := strconv.Itoa(int(cfg.APIEndpoint.BindPort))
|
bindPortString := strconv.Itoa(int(cfg.APIEndpoint.BindPort))
|
||||||
if _, err := ParsePort(bindPortString); err != nil {
|
if _, err := ParsePort(bindPortString); err != nil {
|
||||||
return "", fmt.Errorf("invalid value %q given for api.bindPort: %s", cfg.APIEndpoint.BindPort, err)
|
return "", errors.Wrapf(err, "invalid value %q given for api.bindPort", cfg.APIEndpoint.BindPort)
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse the AdvertiseAddress
|
// parse the AdvertiseAddress
|
||||||
var ip = net.ParseIP(cfg.APIEndpoint.AdvertiseAddress)
|
var ip = net.ParseIP(cfg.APIEndpoint.AdvertiseAddress)
|
||||||
if ip == nil {
|
if ip == nil {
|
||||||
return "", fmt.Errorf("invalid value `%s` given for api.advertiseAddress", cfg.APIEndpoint.AdvertiseAddress)
|
return "", errors.Errorf("invalid value `%s` given for api.advertiseAddress", cfg.APIEndpoint.AdvertiseAddress)
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the master url using cfg.API.AdvertiseAddress + the cfg.API.BindPort
|
// set the master url using cfg.API.AdvertiseAddress + the cfg.API.BindPort
|
||||||
@@ -55,7 +57,7 @@ func GetMasterEndpoint(cfg *kubeadmapi.InitConfiguration) (string, error) {
|
|||||||
var host, port string
|
var host, port string
|
||||||
var err error
|
var err error
|
||||||
if host, port, err = ParseHostPort(cfg.ControlPlaneEndpoint); err != nil {
|
if host, port, err = ParseHostPort(cfg.ControlPlaneEndpoint); err != nil {
|
||||||
return "", fmt.Errorf("invalid value %q given for controlPlaneEndpoint: %s", cfg.ControlPlaneEndpoint, err)
|
return "", errors.Wrapf(err, "invalid value %q given for controlPlaneEndpoint", cfg.ControlPlaneEndpoint)
|
||||||
}
|
}
|
||||||
|
|
||||||
// if a port is provided within the controlPlaneAddress warn the users we are using it, else use the bindport
|
// if a port is provided within the controlPlaneAddress warn the users we are using it, else use the bindport
|
||||||
@@ -93,7 +95,7 @@ func ParseHostPort(hostport string) (string, string, error) {
|
|||||||
// if port is defined, parse and validate it
|
// if port is defined, parse and validate it
|
||||||
if port != "" {
|
if port != "" {
|
||||||
if _, err := ParsePort(port); err != nil {
|
if _, err := ParsePort(port); err != nil {
|
||||||
return "", "", fmt.Errorf("port must be a valid number between 1 and 65535, inclusive")
|
return "", "", errors.New("port must be a valid number between 1 and 65535, inclusive")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,7 +109,7 @@ func ParseHostPort(hostport string) (string, string, error) {
|
|||||||
return host, port, nil
|
return host, port, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return "", "", fmt.Errorf("host must be a valid IP address or a valid RFC-1123 DNS subdomain")
|
return "", "", errors.New("host must be a valid IP address or a valid RFC-1123 DNS subdomain")
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParsePort parses a string representing a TCP port.
|
// ParsePort parses a string representing a TCP port.
|
||||||
@@ -118,5 +120,5 @@ func ParsePort(port string) (int, error) {
|
|||||||
return portInt, nil
|
return portInt, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0, fmt.Errorf("port must be a valid number between 1 and 65535, inclusive")
|
return 0, errors.New("port must be a valid number between 1 and 65535, inclusive")
|
||||||
}
|
}
|
||||||
|
@@ -17,7 +17,7 @@ limitations under the License.
|
|||||||
package util
|
package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"github.com/pkg/errors"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ func TestCheckErr(t *testing.T) {
|
|||||||
expected int
|
expected int
|
||||||
}{
|
}{
|
||||||
{nil, 0},
|
{nil, 0},
|
||||||
{fmt.Errorf(""), DefaultErrorExitCode},
|
{errors.New(""), DefaultErrorExitCode},
|
||||||
{&pferror{}, PreFlightExitCode},
|
{&pferror{}, PreFlightExitCode},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,14 +63,14 @@ func TestFormatErrMsg(t *testing.T) {
|
|||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
errs: []error{
|
errs: []error{
|
||||||
fmt.Errorf(errMsg1),
|
errors.New(errMsg1),
|
||||||
fmt.Errorf(errMsg2),
|
errors.New(errMsg2),
|
||||||
},
|
},
|
||||||
expect: "\t- " + errMsg1 + "\n" + "\t- " + errMsg2 + "\n",
|
expect: "\t- " + errMsg1 + "\n" + "\t- " + errMsg2 + "\n",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
errs: []error{
|
errs: []error{
|
||||||
fmt.Errorf(errMsg1),
|
errors.New(errMsg1),
|
||||||
},
|
},
|
||||||
expect: "\t- " + errMsg1 + "\n",
|
expect: "\t- " + errMsg1 + "\n",
|
||||||
},
|
},
|
||||||
|
@@ -117,7 +117,7 @@ func New(endpoints []string, ca, cert, key string) (*Client, error) {
|
|||||||
func NewFromStaticPod(endpoints []string, manifestDir string, certificatesDir string) (*Client, error) {
|
func NewFromStaticPod(endpoints []string, manifestDir string, certificatesDir string) (*Client, error) {
|
||||||
hasTLS, err := PodManifestsHaveTLS(manifestDir)
|
hasTLS, err := PodManifestsHaveTLS(manifestDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("could not read manifests from: %s, error: %v", manifestDir, err)
|
return nil, errors.Wrapf(err, "could not read manifests from: %s, error", manifestDir)
|
||||||
}
|
}
|
||||||
if hasTLS {
|
if hasTLS {
|
||||||
return New(
|
return New(
|
||||||
@@ -243,7 +243,7 @@ func (c Client) GetVersion() (string, error) {
|
|||||||
}
|
}
|
||||||
for _, v := range versions {
|
for _, v := range versions {
|
||||||
if clusterVersion != "" && clusterVersion != v {
|
if clusterVersion != "" && clusterVersion != v {
|
||||||
return "", fmt.Errorf("etcd cluster contains endpoints with mismatched versions: %v", versions)
|
return "", errors.Errorf("etcd cluster contains endpoints with mismatched versions: %v", versions)
|
||||||
}
|
}
|
||||||
clusterVersion = v
|
clusterVersion = v
|
||||||
}
|
}
|
||||||
|
@@ -19,10 +19,10 @@ package util
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/ghodss/yaml"
|
"github.com/ghodss/yaml"
|
||||||
|
pkgerrors "github.com/pkg/errors"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
@@ -45,7 +45,7 @@ func MarshalToYamlForCodecs(obj runtime.Object, gv schema.GroupVersion, codecs s
|
|||||||
mediaType := "application/yaml"
|
mediaType := "application/yaml"
|
||||||
info, ok := runtime.SerializerInfoForMediaType(codecs.SupportedMediaTypes(), mediaType)
|
info, ok := runtime.SerializerInfoForMediaType(codecs.SupportedMediaTypes(), mediaType)
|
||||||
if !ok {
|
if !ok {
|
||||||
return []byte{}, fmt.Errorf("unsupported media type %q", mediaType)
|
return []byte{}, pkgerrors.Errorf("unsupported media type %q", mediaType)
|
||||||
}
|
}
|
||||||
|
|
||||||
encoder := codecs.EncoderForVersion(info.Serializer, gv)
|
encoder := codecs.EncoderForVersion(info.Serializer, gv)
|
||||||
@@ -64,7 +64,7 @@ func UnmarshalFromYamlForCodecs(buffer []byte, gv schema.GroupVersion, codecs se
|
|||||||
mediaType := "application/yaml"
|
mediaType := "application/yaml"
|
||||||
info, ok := runtime.SerializerInfoForMediaType(codecs.SupportedMediaTypes(), mediaType)
|
info, ok := runtime.SerializerInfoForMediaType(codecs.SupportedMediaTypes(), mediaType)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("unsupported media type %q", mediaType)
|
return nil, pkgerrors.Errorf("unsupported media type %q", mediaType)
|
||||||
}
|
}
|
||||||
|
|
||||||
decoder := codecs.DecoderToVersion(info.Serializer, gv)
|
decoder := codecs.DecoderToVersion(info.Serializer, gv)
|
||||||
@@ -97,12 +97,12 @@ func SplitYAMLDocuments(yamlBytes []byte) (map[schema.GroupVersionKind][]byte, e
|
|||||||
}
|
}
|
||||||
// Require TypeMeta information to be present
|
// Require TypeMeta information to be present
|
||||||
if len(typeMetaInfo.APIVersion) == 0 || len(typeMetaInfo.Kind) == 0 {
|
if len(typeMetaInfo.APIVersion) == 0 || len(typeMetaInfo.Kind) == 0 {
|
||||||
errs = append(errs, fmt.Errorf("invalid configuration: kind and apiVersion is mandatory information that needs to be specified in all YAML documents"))
|
errs = append(errs, pkgerrors.New("invalid configuration: kind and apiVersion is mandatory information that needs to be specified in all YAML documents"))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// Check whether the kind has been registered before. If it has, throw an error
|
// Check whether the kind has been registered before. If it has, throw an error
|
||||||
if known := knownKinds[typeMetaInfo.Kind]; known {
|
if known := knownKinds[typeMetaInfo.Kind]; known {
|
||||||
errs = append(errs, fmt.Errorf("invalid configuration: kind %q is specified twice in YAML file", typeMetaInfo.Kind))
|
errs = append(errs, pkgerrors.Errorf("invalid configuration: kind %q is specified twice in YAML file", typeMetaInfo.Kind))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
knownKinds[typeMetaInfo.Kind] = true
|
knownKinds[typeMetaInfo.Kind] = true
|
||||||
@@ -110,7 +110,7 @@ func SplitYAMLDocuments(yamlBytes []byte) (map[schema.GroupVersionKind][]byte, e
|
|||||||
// Build a GroupVersionKind object from the deserialized TypeMeta object
|
// Build a GroupVersionKind object from the deserialized TypeMeta object
|
||||||
gv, err := schema.ParseGroupVersion(typeMetaInfo.APIVersion)
|
gv, err := schema.ParseGroupVersion(typeMetaInfo.APIVersion)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errs = append(errs, fmt.Errorf("unable to parse apiVersion: %v", err))
|
errs = append(errs, pkgerrors.Wrap(err, "unable to parse apiVersion"))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
gvk := gv.WithKind(typeMetaInfo.Kind)
|
gvk := gv.WithKind(typeMetaInfo.Kind)
|
||||||
|
@@ -22,8 +22,9 @@ import (
|
|||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -46,7 +47,7 @@ func (s *Set) Allow(pubKeyHashes ...string) error {
|
|||||||
for _, pubKeyHash := range pubKeyHashes {
|
for _, pubKeyHash := range pubKeyHashes {
|
||||||
parts := strings.Split(pubKeyHash, ":")
|
parts := strings.Split(pubKeyHash, ":")
|
||||||
if len(parts) != 2 {
|
if len(parts) != 2 {
|
||||||
return fmt.Errorf("invalid public key hash, expected \"format:value\"")
|
return errors.New("invalid public key hash, expected \"format:value\"")
|
||||||
}
|
}
|
||||||
format, value := parts[0], parts[1]
|
format, value := parts[0], parts[1]
|
||||||
|
|
||||||
@@ -54,7 +55,7 @@ func (s *Set) Allow(pubKeyHashes ...string) error {
|
|||||||
case "sha256":
|
case "sha256":
|
||||||
return s.allowSHA256(value)
|
return s.allowSHA256(value)
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("unknown hash format %q", format)
|
return errors.Errorf("unknown hash format %q", format)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -65,7 +66,7 @@ func (s *Set) Check(certificate *x509.Certificate) error {
|
|||||||
if s.checkSHA256(certificate) {
|
if s.checkSHA256(certificate) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("public key %s not pinned", Hash(certificate))
|
return errors.Errorf("public key %s not pinned", Hash(certificate))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Empty returns true if the Set contains no pinned public keys.
|
// Empty returns true if the Set contains no pinned public keys.
|
||||||
@@ -86,7 +87,7 @@ func (s *Set) allowSHA256(hash string) error {
|
|||||||
// validate that the hash is the right length to be a full SHA-256 hash
|
// validate that the hash is the right length to be a full SHA-256 hash
|
||||||
hashLength := hex.DecodedLen(len(hash))
|
hashLength := hex.DecodedLen(len(hash))
|
||||||
if hashLength != sha256.Size {
|
if hashLength != sha256.Size {
|
||||||
return fmt.Errorf("expected a %d byte SHA-256 hash, found %d bytes", sha256.Size, hashLength)
|
return errors.Errorf("expected a %d byte SHA-256 hash, found %d bytes", sha256.Size, hashLength)
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate that the hash is valid hex
|
// validate that the hash is valid hex
|
||||||
|
@@ -17,11 +17,12 @@ limitations under the License.
|
|||||||
package util
|
package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
goruntime "runtime"
|
goruntime "runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
pkgerrors "github.com/pkg/errors"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/util/errors"
|
"k8s.io/apimachinery/pkg/util/errors"
|
||||||
kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1"
|
kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1"
|
||||||
utilsexec "k8s.io/utils/exec"
|
utilsexec "k8s.io/utils/exec"
|
||||||
@@ -68,7 +69,7 @@ func NewContainerRuntime(execer utilsexec.Interface, criSocket string) (Containe
|
|||||||
}
|
}
|
||||||
|
|
||||||
if _, err := execer.LookPath(toolName); err != nil {
|
if _, err := execer.LookPath(toolName); err != nil {
|
||||||
return nil, fmt.Errorf("%s is required for container runtime: %v", toolName, err)
|
return nil, pkgerrors.Wrapf(err, "%s is required for container runtime", toolName)
|
||||||
}
|
}
|
||||||
|
|
||||||
return runtime, nil
|
return runtime, nil
|
||||||
@@ -87,7 +88,7 @@ func (runtime *DockerRuntime) IsDocker() bool {
|
|||||||
// IsRunning checks if runtime is running
|
// IsRunning checks if runtime is running
|
||||||
func (runtime *CRIRuntime) IsRunning() error {
|
func (runtime *CRIRuntime) IsRunning() error {
|
||||||
if out, err := runtime.exec.Command("crictl", "-r", runtime.criSocket, "info").CombinedOutput(); err != nil {
|
if out, err := runtime.exec.Command("crictl", "-r", runtime.criSocket, "info").CombinedOutput(); err != nil {
|
||||||
return fmt.Errorf("container runtime is not running: output: %s, error: %v", string(out), err)
|
return pkgerrors.Wrapf(err, "container runtime is not running: output: %s, error", string(out))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -95,7 +96,7 @@ func (runtime *CRIRuntime) IsRunning() error {
|
|||||||
// IsRunning checks if runtime is running
|
// IsRunning checks if runtime is running
|
||||||
func (runtime *DockerRuntime) IsRunning() error {
|
func (runtime *DockerRuntime) IsRunning() error {
|
||||||
if out, err := runtime.exec.Command("docker", "info").CombinedOutput(); err != nil {
|
if out, err := runtime.exec.Command("docker", "info").CombinedOutput(); err != nil {
|
||||||
return fmt.Errorf("container runtime is not running: output: %s, error: %v", string(out), err)
|
return pkgerrors.Wrapf(err, "container runtime is not running: output: %s, error", string(out))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -104,7 +105,7 @@ func (runtime *DockerRuntime) IsRunning() error {
|
|||||||
func (runtime *CRIRuntime) ListKubeContainers() ([]string, error) {
|
func (runtime *CRIRuntime) ListKubeContainers() ([]string, error) {
|
||||||
out, err := runtime.exec.Command("crictl", "-r", runtime.criSocket, "pods", "-q").CombinedOutput()
|
out, err := runtime.exec.Command("crictl", "-r", runtime.criSocket, "pods", "-q").CombinedOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("output: %s, error: %v", string(out), err)
|
return nil, pkgerrors.Wrapf(err, "output: %s, error", string(out))
|
||||||
}
|
}
|
||||||
pods := []string{}
|
pods := []string{}
|
||||||
for _, pod := range strings.Fields(string(out)) {
|
for _, pod := range strings.Fields(string(out)) {
|
||||||
@@ -126,11 +127,11 @@ func (runtime *CRIRuntime) RemoveContainers(containers []string) error {
|
|||||||
out, err := runtime.exec.Command("crictl", "-r", runtime.criSocket, "stopp", container).CombinedOutput()
|
out, err := runtime.exec.Command("crictl", "-r", runtime.criSocket, "stopp", container).CombinedOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// don't stop on errors, try to remove as many containers as possible
|
// don't stop on errors, try to remove as many containers as possible
|
||||||
errs = append(errs, fmt.Errorf("failed to stop running pod %s: output: %s, error: %v", container, string(out), err))
|
errs = append(errs, pkgerrors.Wrapf(err, "failed to stop running pod %s: output: %s, error", container, string(out)))
|
||||||
} else {
|
} else {
|
||||||
out, err = runtime.exec.Command("crictl", "-r", runtime.criSocket, "rmp", container).CombinedOutput()
|
out, err = runtime.exec.Command("crictl", "-r", runtime.criSocket, "rmp", container).CombinedOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errs = append(errs, fmt.Errorf("failed to remove running container %s: output: %s, error: %v", container, string(out), err))
|
errs = append(errs, pkgerrors.Wrapf(err, "failed to remove running container %s: output: %s, error", container, string(out)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -144,7 +145,7 @@ func (runtime *DockerRuntime) RemoveContainers(containers []string) error {
|
|||||||
out, err := runtime.exec.Command("docker", "rm", "--force", "--volumes", container).CombinedOutput()
|
out, err := runtime.exec.Command("docker", "rm", "--force", "--volumes", container).CombinedOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// don't stop on errors, try to remove as many containers as possible
|
// don't stop on errors, try to remove as many containers as possible
|
||||||
errs = append(errs, fmt.Errorf("failed to remove running container %s: output: %s, error: %v", container, string(out), err))
|
errs = append(errs, pkgerrors.Wrapf(err, "failed to remove running container %s: output: %s, error", container, string(out)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return errors.NewAggregate(errs)
|
return errors.NewAggregate(errs)
|
||||||
@@ -154,7 +155,7 @@ func (runtime *DockerRuntime) RemoveContainers(containers []string) error {
|
|||||||
func (runtime *CRIRuntime) PullImage(image string) error {
|
func (runtime *CRIRuntime) PullImage(image string) error {
|
||||||
out, err := runtime.exec.Command("crictl", "-r", runtime.criSocket, "pull", image).CombinedOutput()
|
out, err := runtime.exec.Command("crictl", "-r", runtime.criSocket, "pull", image).CombinedOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("output: %s, error: %v", string(out), err)
|
return pkgerrors.Wrapf(err, "output: %s, error", string(out))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -163,7 +164,7 @@ func (runtime *CRIRuntime) PullImage(image string) error {
|
|||||||
func (runtime *DockerRuntime) PullImage(image string) error {
|
func (runtime *DockerRuntime) PullImage(image string) error {
|
||||||
out, err := runtime.exec.Command("docker", "pull", image).CombinedOutput()
|
out, err := runtime.exec.Command("docker", "pull", image).CombinedOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("output: %s, error: %v", string(out), err)
|
return pkgerrors.Wrapf(err, "output: %s, error", string(out))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@@ -17,10 +17,11 @@ limitations under the License.
|
|||||||
package util
|
package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1"
|
kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1"
|
||||||
"k8s.io/utils/exec"
|
"k8s.io/utils/exec"
|
||||||
fakeexec "k8s.io/utils/exec/testing"
|
fakeexec "k8s.io/utils/exec/testing"
|
||||||
@@ -31,7 +32,7 @@ func TestNewContainerRuntime(t *testing.T) {
|
|||||||
LookPathFunc: func(cmd string) (string, error) { return "/usr/bin/crictl", nil },
|
LookPathFunc: func(cmd string) (string, error) { return "/usr/bin/crictl", nil },
|
||||||
}
|
}
|
||||||
execLookPathErr := fakeexec.FakeExec{
|
execLookPathErr := fakeexec.FakeExec{
|
||||||
LookPathFunc: func(cmd string) (string, error) { return "", fmt.Errorf("%s not found", cmd) },
|
LookPathFunc: func(cmd string) (string, error) { return "", errors.Errorf("%s not found", cmd) },
|
||||||
}
|
}
|
||||||
cases := []struct {
|
cases := []struct {
|
||||||
name string
|
name string
|
||||||
|
@@ -26,8 +26,9 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"k8s.io/api/core/v1"
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
|
"k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/api/resource"
|
"k8s.io/apimachinery/pkg/api/resource"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/util/intstr"
|
"k8s.io/apimachinery/pkg/util/intstr"
|
||||||
@@ -192,19 +193,19 @@ func WriteStaticPodToDisk(componentName, manifestDir string, pod v1.Pod) error {
|
|||||||
|
|
||||||
// creates target folder if not already exists
|
// creates target folder if not already exists
|
||||||
if err := os.MkdirAll(manifestDir, 0700); err != nil {
|
if err := os.MkdirAll(manifestDir, 0700); err != nil {
|
||||||
return fmt.Errorf("failed to create directory %q: %v", manifestDir, err)
|
return errors.Wrapf(err, "failed to create directory %q", manifestDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
// writes the pod to disk
|
// writes the pod to disk
|
||||||
serialized, err := util.MarshalToYaml(&pod, v1.SchemeGroupVersion)
|
serialized, err := util.MarshalToYaml(&pod, v1.SchemeGroupVersion)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to marshal manifest for %q to YAML: %v", componentName, err)
|
return errors.Wrapf(err, "failed to marshal manifest for %q to YAML", componentName)
|
||||||
}
|
}
|
||||||
|
|
||||||
filename := kubeadmconstants.GetStaticPodFilepath(componentName, manifestDir)
|
filename := kubeadmconstants.GetStaticPodFilepath(componentName, manifestDir)
|
||||||
|
|
||||||
if err := ioutil.WriteFile(filename, serialized, 0600); err != nil {
|
if err := ioutil.WriteFile(filename, serialized, 0600); err != nil {
|
||||||
return fmt.Errorf("failed to write static pod manifest file for %q (%q): %v", componentName, filename, err)
|
return errors.Wrapf(err, "failed to write static pod manifest file for %q (%q)", componentName, filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -214,12 +215,12 @@ func WriteStaticPodToDisk(componentName, manifestDir string, pod v1.Pod) error {
|
|||||||
func ReadStaticPodFromDisk(manifestPath string) (*v1.Pod, error) {
|
func ReadStaticPodFromDisk(manifestPath string) (*v1.Pod, error) {
|
||||||
buf, err := ioutil.ReadFile(manifestPath)
|
buf, err := ioutil.ReadFile(manifestPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &v1.Pod{}, fmt.Errorf("failed to read manifest for %q: %v", manifestPath, err)
|
return &v1.Pod{}, errors.Wrapf(err, "failed to read manifest for %q", manifestPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
obj, err := util.UnmarshalFromYaml(buf, v1.SchemeGroupVersion)
|
obj, err := util.UnmarshalFromYaml(buf, v1.SchemeGroupVersion)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &v1.Pod{}, fmt.Errorf("failed to unmarshal manifest for %q from YAML: %v", manifestPath, err)
|
return &v1.Pod{}, errors.Errorf("failed to unmarshal manifest for %q from YAML: %v", manifestPath, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
pod := obj.(*v1.Pod)
|
pod := obj.(*v1.Pod)
|
||||||
|
@@ -18,7 +18,6 @@ package system
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@@ -66,7 +65,7 @@ func (c *CgroupsValidator) validateCgroupSubsystems(cgroupSpec, subsystems []str
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(missing) > 0 {
|
if len(missing) > 0 {
|
||||||
return fmt.Errorf("missing cgroups: %s", strings.Join(missing, " "))
|
return errors.Errorf("missing cgroups: %s", strings.Join(missing, " "))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
|
@@ -18,7 +18,6 @@ package system
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"regexp"
|
"regexp"
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
@@ -78,7 +77,7 @@ func (d *DockerValidator) validateDockerInfo(spec *DockerSpec, info types.Info)
|
|||||||
r := regexp.MustCompile(ver)
|
r := regexp.MustCompile(ver)
|
||||||
if r.MatchString(info.ServerVersion) {
|
if r.MatchString(info.ServerVersion) {
|
||||||
d.Reporter.Report(dockerConfigPrefix+"VERSION", info.ServerVersion, good)
|
d.Reporter.Report(dockerConfigPrefix+"VERSION", info.ServerVersion, good)
|
||||||
w := fmt.Errorf(
|
w := errors.Errorf(
|
||||||
"this Docker version is not on the list of validated versions: %s. Latest validated version: %s",
|
"this Docker version is not on the list of validated versions: %s. Latest validated version: %s",
|
||||||
info.ServerVersion,
|
info.ServerVersion,
|
||||||
latestValidatedDockerVersion,
|
latestValidatedDockerVersion,
|
||||||
@@ -86,7 +85,7 @@ func (d *DockerValidator) validateDockerInfo(spec *DockerSpec, info types.Info)
|
|||||||
return w, nil
|
return w, nil
|
||||||
}
|
}
|
||||||
d.Reporter.Report(dockerConfigPrefix+"VERSION", info.ServerVersion, bad)
|
d.Reporter.Report(dockerConfigPrefix+"VERSION", info.ServerVersion, bad)
|
||||||
return nil, fmt.Errorf("unsupported docker version: %s", info.ServerVersion)
|
return nil, errors.Errorf("unsupported docker version: %s", info.ServerVersion)
|
||||||
}
|
}
|
||||||
// Validate graph driver.
|
// Validate graph driver.
|
||||||
item := dockerConfigPrefix + "GRAPH_DRIVER"
|
item := dockerConfigPrefix + "GRAPH_DRIVER"
|
||||||
@@ -97,5 +96,5 @@ func (d *DockerValidator) validateDockerInfo(spec *DockerSpec, info types.Info)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
d.Reporter.Report(item, info.Driver, bad)
|
d.Reporter.Report(item, info.Driver, bad)
|
||||||
return nil, fmt.Errorf("unsupported graph driver: %s", info.Driver)
|
return nil, errors.Errorf("unsupported graph driver: %s", info.Driver)
|
||||||
}
|
}
|
||||||
|
@@ -30,6 +30,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
|
pkgerrors "github.com/pkg/errors"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/util/errors"
|
"k8s.io/apimachinery/pkg/util/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -64,7 +66,7 @@ func (k *KernelValidator) Validate(spec SysSpec) (error, error) {
|
|||||||
helper := KernelValidatorHelperImpl{}
|
helper := KernelValidatorHelperImpl{}
|
||||||
release, err := helper.GetKernelReleaseVersion()
|
release, err := helper.GetKernelReleaseVersion()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to get kernel release: %v", err)
|
return nil, pkgerrors.Wrap(err, "failed to get kernel release")
|
||||||
}
|
}
|
||||||
k.kernelRelease = release
|
k.kernelRelease = release
|
||||||
var errs []error
|
var errs []error
|
||||||
@@ -87,14 +89,14 @@ func (k *KernelValidator) validateKernelVersion(kSpec KernelSpec) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
k.Reporter.Report("KERNEL_VERSION", k.kernelRelease, bad)
|
k.Reporter.Report("KERNEL_VERSION", k.kernelRelease, bad)
|
||||||
return fmt.Errorf("unsupported kernel release: %s", k.kernelRelease)
|
return pkgerrors.Errorf("unsupported kernel release: %s", k.kernelRelease)
|
||||||
}
|
}
|
||||||
|
|
||||||
// validateKernelConfig validates the kernel configurations.
|
// validateKernelConfig validates the kernel configurations.
|
||||||
func (k *KernelValidator) validateKernelConfig(kSpec KernelSpec) error {
|
func (k *KernelValidator) validateKernelConfig(kSpec KernelSpec) error {
|
||||||
allConfig, err := k.getKernelConfig()
|
allConfig, err := k.getKernelConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to parse kernel config: %v", err)
|
return pkgerrors.Wrap(err, "failed to parse kernel config")
|
||||||
}
|
}
|
||||||
return k.validateCachedKernelConfig(allConfig, kSpec)
|
return k.validateCachedKernelConfig(allConfig, kSpec)
|
||||||
}
|
}
|
||||||
@@ -163,7 +165,7 @@ func (k *KernelValidator) validateCachedKernelConfig(allConfig map[string]kConfi
|
|||||||
validateOpt(config, forbidden)
|
validateOpt(config, forbidden)
|
||||||
}
|
}
|
||||||
if len(badConfigs) > 0 {
|
if len(badConfigs) > 0 {
|
||||||
return fmt.Errorf("unexpected kernel config: %s", strings.Join(badConfigs, " "))
|
return pkgerrors.Errorf("unexpected kernel config: %s", strings.Join(badConfigs, " "))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -218,14 +220,14 @@ func (k *KernelValidator) getKernelConfigReader() (io.Reader, error) {
|
|||||||
// config module and check again.
|
// config module and check again.
|
||||||
output, err := exec.Command(modprobeCmd, configsModule).CombinedOutput()
|
output, err := exec.Command(modprobeCmd, configsModule).CombinedOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unable to load kernel module %q: output - %q, err - %v",
|
return nil, pkgerrors.Wrapf(err, "unable to load kernel module: %q, output: %q, err",
|
||||||
configsModule, output, err)
|
configsModule, output)
|
||||||
}
|
}
|
||||||
// Unload the kernel config module to make sure the validation have no side effect.
|
// Unload the kernel config module to make sure the validation have no side effect.
|
||||||
defer exec.Command(modprobeCmd, "-r", configsModule).Run()
|
defer exec.Command(modprobeCmd, "-r", configsModule).Run()
|
||||||
loadModule = true
|
loadModule = true
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("no config path in %v is available", possibePaths)
|
return nil, pkgerrors.Errorf("no config path in %v is available", possibePaths)
|
||||||
}
|
}
|
||||||
|
|
||||||
// getKernelConfig gets kernel config from kernel config file and convert kernel config to internal type.
|
// getKernelConfig gets kernel config from kernel config file and convert kernel config to internal type.
|
||||||
|
@@ -17,7 +17,6 @@ limitations under the License.
|
|||||||
package system
|
package system
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@@ -45,7 +44,7 @@ func (o *OSValidator) Validate(spec SysSpec) (error, error) {
|
|||||||
func (o *OSValidator) validateOS(os, specOS string) error {
|
func (o *OSValidator) validateOS(os, specOS string) error {
|
||||||
if os != specOS {
|
if os != specOS {
|
||||||
o.Reporter.Report("OS", os, bad)
|
o.Reporter.Report("OS", os, bad)
|
||||||
return fmt.Errorf("unsupported operating system: %s", os)
|
return errors.Errorf("unsupported operating system: %s", os)
|
||||||
}
|
}
|
||||||
o.Reporter.Report("OS", os, good)
|
o.Reporter.Report("OS", os, good)
|
||||||
return nil
|
return nil
|
||||||
|
@@ -26,6 +26,7 @@ import (
|
|||||||
|
|
||||||
"github.com/blang/semver"
|
"github.com/blang/semver"
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
|
pkgerrors "github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// semVerDotsCount is the number of dots in a valid semantic version.
|
// semVerDotsCount is the number of dots in a valid semantic version.
|
||||||
@@ -45,7 +46,7 @@ func newPackageManager() (packageManager, error) {
|
|||||||
if m, ok := newDPKG(); ok {
|
if m, ok := newDPKG(); ok {
|
||||||
return m, nil
|
return m, nil
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("failed to find package manager")
|
return nil, pkgerrors.New("failed to find package manager")
|
||||||
}
|
}
|
||||||
|
|
||||||
// dpkg implements packageManager. It uses "dpkg-query" to retrieve package
|
// dpkg implements packageManager. It uses "dpkg-query" to retrieve package
|
||||||
@@ -67,11 +68,11 @@ func newDPKG() (packageManager, bool) {
|
|||||||
func (_ dpkg) getPackageVersion(packageName string) (string, error) {
|
func (_ dpkg) getPackageVersion(packageName string) (string, error) {
|
||||||
output, err := exec.Command("dpkg-query", "--show", "--showformat='${Version}'", packageName).Output()
|
output, err := exec.Command("dpkg-query", "--show", "--showformat='${Version}'", packageName).Output()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("dpkg-query failed: %s", err)
|
return "", pkgerrors.Wrap(err, "dpkg-query failed")
|
||||||
}
|
}
|
||||||
version := extractUpstreamVersion(string(output))
|
version := extractUpstreamVersion(string(output))
|
||||||
if version == "" {
|
if version == "" {
|
||||||
return "", fmt.Errorf("no version information")
|
return "", pkgerrors.New("no version information")
|
||||||
}
|
}
|
||||||
return version, nil
|
return version, nil
|
||||||
}
|
}
|
||||||
@@ -153,7 +154,7 @@ func (self *packageValidator) validate(packageSpecs []PackageSpec, manager packa
|
|||||||
if versionRange(sv) {
|
if versionRange(sv) {
|
||||||
self.reporter.Report(nameWithVerRange, version, good)
|
self.reporter.Report(nameWithVerRange, version, good)
|
||||||
} else {
|
} else {
|
||||||
errs = append(errs, fmt.Errorf("package \"%s %s\" does not meet the spec \"%s (%s)\"", packageName, sv, packageName, spec.VersionRange))
|
errs = append(errs, pkgerrors.Errorf("package \"%s %s\" does not meet the spec \"%s (%s)\"", packageName, sv, packageName, spec.VersionRange))
|
||||||
self.reporter.Report(nameWithVerRange, version, bad)
|
self.reporter.Report(nameWithVerRange, version, bad)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -164,7 +165,7 @@ func (self *packageValidator) validate(packageSpecs []PackageSpec, manager packa
|
|||||||
func getKernelRelease() (string, error) {
|
func getKernelRelease() (string, error) {
|
||||||
output, err := exec.Command("uname", "-r").Output()
|
output, err := exec.Command("uname", "-r").Output()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("failed to get kernel release: %s", err)
|
return "", pkgerrors.Wrap(err, "failed to get kernel release")
|
||||||
}
|
}
|
||||||
return strings.TrimSpace(string(output)), nil
|
return strings.TrimSpace(string(output)), nil
|
||||||
}
|
}
|
||||||
@@ -174,7 +175,7 @@ func getOSDistro() (string, error) {
|
|||||||
f := "/etc/lsb-release"
|
f := "/etc/lsb-release"
|
||||||
b, err := ioutil.ReadFile(f)
|
b, err := ioutil.ReadFile(f)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("failed to read %q: %s", f, err)
|
return "", pkgerrors.Wrapf(err, "failed to read %q", f)
|
||||||
}
|
}
|
||||||
content := string(b)
|
content := string(b)
|
||||||
switch {
|
switch {
|
||||||
@@ -185,7 +186,7 @@ func getOSDistro() (string, error) {
|
|||||||
case strings.Contains(content, "CoreOS"):
|
case strings.Contains(content, "CoreOS"):
|
||||||
return "coreos", nil
|
return "coreos", nil
|
||||||
default:
|
default:
|
||||||
return "", fmt.Errorf("failed to get OS distro: %s", content)
|
return "", pkgerrors.Errorf("failed to get OS distro: %s", content)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -17,10 +17,10 @@ limitations under the License.
|
|||||||
package system
|
package system
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestExtractUpstreamVersion(t *testing.T) {
|
func TestExtractUpstreamVersion(t *testing.T) {
|
||||||
@@ -159,7 +159,7 @@ func (m testPackageManager) getPackageVersion(packageName string) (string, error
|
|||||||
if v, ok := m.packageVersions[packageName]; ok {
|
if v, ok := m.packageVersions[packageName]; ok {
|
||||||
return v, nil
|
return v, nil
|
||||||
}
|
}
|
||||||
return "", fmt.Errorf("package %q does not exist", packageName)
|
return "", errors.Errorf("package %q does not exist", packageName)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestValidatePackageVersion(t *testing.T) {
|
func TestValidatePackageVersion(t *testing.T) {
|
||||||
|
@@ -18,6 +18,7 @@ package system
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/pkg/errors"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
@@ -65,7 +66,7 @@ func (dr *StreamReporter) Report(key, value string, resultType ValidationResultT
|
|||||||
c = white
|
c = white
|
||||||
}
|
}
|
||||||
if dr.WriteStream == nil {
|
if dr.WriteStream == nil {
|
||||||
return fmt.Errorf("WriteStream has to be defined for this reporter")
|
return errors.New("WriteStream has to be defined for this reporter")
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprintf(dr.WriteStream, "%s: %s\n", colorize(key, white), colorize(value, c))
|
fmt.Fprintf(dr.WriteStream, "%s: %s\n", colorize(key, white), colorize(value, c))
|
||||||
|
@@ -26,6 +26,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
|
pkgerrors "github.com/pkg/errors"
|
||||||
netutil "k8s.io/apimachinery/pkg/util/net"
|
netutil "k8s.io/apimachinery/pkg/util/net"
|
||||||
versionutil "k8s.io/apimachinery/pkg/util/version"
|
versionutil "k8s.io/apimachinery/pkg/util/version"
|
||||||
pkgversion "k8s.io/kubernetes/pkg/version"
|
pkgversion "k8s.io/kubernetes/pkg/version"
|
||||||
@@ -102,7 +103,7 @@ func KubernetesReleaseVersion(version string) (string, error) {
|
|||||||
// Re-validate received version and return.
|
// Re-validate received version and return.
|
||||||
return KubernetesReleaseVersion(body)
|
return KubernetesReleaseVersion(body)
|
||||||
}
|
}
|
||||||
return "", fmt.Errorf("version %q doesn't match patterns for neither semantic version nor labels (stable, latest, ...)", version)
|
return "", pkgerrors.Errorf("version %q doesn't match patterns for neither semantic version nor labels (stable, latest, ...)", version)
|
||||||
}
|
}
|
||||||
|
|
||||||
// KubernetesVersionToImageTag is helper function that replaces all
|
// KubernetesVersionToImageTag is helper function that replaces all
|
||||||
@@ -143,7 +144,7 @@ func splitVersion(version string) (string, string, error) {
|
|||||||
var urlSuffix string
|
var urlSuffix string
|
||||||
subs := kubeBucketPrefixes.FindAllStringSubmatch(version, 1)
|
subs := kubeBucketPrefixes.FindAllStringSubmatch(version, 1)
|
||||||
if len(subs) != 1 || len(subs[0]) != 4 {
|
if len(subs) != 1 || len(subs[0]) != 4 {
|
||||||
return "", "", fmt.Errorf("invalid version %q", version)
|
return "", "", pkgerrors.Errorf("invalid version %q", version)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
@@ -163,12 +164,12 @@ func fetchFromURL(url string, timeout time.Duration) (string, error) {
|
|||||||
client := &http.Client{Timeout: timeout, Transport: netutil.SetOldTransportDefaults(&http.Transport{})}
|
client := &http.Client{Timeout: timeout, Transport: netutil.SetOldTransportDefaults(&http.Transport{})}
|
||||||
resp, err := client.Get(url)
|
resp, err := client.Get(url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("unable to get URL %q: %s", url, err.Error())
|
return "", pkgerrors.Errorf("unable to get URL %q: %s", url, err.Error())
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
body, err := ioutil.ReadAll(resp.Body)
|
body, err := ioutil.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("unable to read content of URL %q: %s", url, err.Error())
|
return "", pkgerrors.Errorf("unable to read content of URL %q: %s", url, err.Error())
|
||||||
}
|
}
|
||||||
bodyString := strings.TrimSpace(string(body))
|
bodyString := strings.TrimSpace(string(body))
|
||||||
|
|
||||||
@@ -183,7 +184,7 @@ func fetchFromURL(url string, timeout time.Duration) (string, error) {
|
|||||||
func kubeadmVersion(info string) (string, error) {
|
func kubeadmVersion(info string) (string, error) {
|
||||||
v, err := versionutil.ParseSemantic(info)
|
v, err := versionutil.ParseSemantic(info)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("kubeadm version error: %v", err)
|
return "", pkgerrors.Wrap(err, "kubeadm version error")
|
||||||
}
|
}
|
||||||
// There is no utility in versionutil to get the version without the metadata,
|
// There is no utility in versionutil to get the version without the metadata,
|
||||||
// so this needs some manual formatting.
|
// so this needs some manual formatting.
|
||||||
@@ -222,11 +223,11 @@ func validateStableVersion(remoteVersion, clientVersion string) (string, error)
|
|||||||
|
|
||||||
verRemote, err := versionutil.ParseGeneric(remoteVersion)
|
verRemote, err := versionutil.ParseGeneric(remoteVersion)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("remote version error: %v", err)
|
return "", pkgerrors.Wrap(err, "remote version error")
|
||||||
}
|
}
|
||||||
verClient, err := versionutil.ParseGeneric(clientVersion)
|
verClient, err := versionutil.ParseGeneric(clientVersion)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("client version error: %v", err)
|
return "", pkgerrors.Wrap(err, "client version error")
|
||||||
}
|
}
|
||||||
// If the remote Major version is bigger or if the Major versions are the same,
|
// If the remote Major version is bigger or if the Major versions are the same,
|
||||||
// but the remote Minor is bigger use the client version release. This handles Major bumps too.
|
// but the remote Minor is bigger use the client version release. This handles Major bumps too.
|
||||||
|
@@ -18,7 +18,7 @@ package kubeadm
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"github.com/pkg/errors"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@@ -37,8 +37,8 @@ func RunCmd(command string, args ...string) (string, string, error) {
|
|||||||
err := cmd.Run()
|
err := cmd.Run()
|
||||||
stdout, stderr := bout.String(), berr.String()
|
stdout, stderr := bout.String(), berr.String()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", fmt.Errorf("error running %s %v; \ngot error %v, \nstdout %q, \nstderr %q",
|
return "", "", errors.Wrapf(err, "error running %s %v; \nstdout %q, \nstderr %q, \ngot error",
|
||||||
command, args, err, stdout, stderr)
|
command, args, stdout, stderr)
|
||||||
}
|
}
|
||||||
return stdout, stderr, nil
|
return stdout, stderr, nil
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user