Skip to content

Commit

Permalink
kubeadm.KubeADM interface
Browse files Browse the repository at this point in the history
Signed-off-by: Artiom Diomin <[email protected]>
  • Loading branch information
kron4eg committed Jun 11, 2019
1 parent 91fa3c9 commit 586cca2
Show file tree
Hide file tree
Showing 8 changed files with 156 additions and 33 deletions.
1 change: 1 addition & 0 deletions pkg/installer/installation/controlplane.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ func joinControlPlaneNodeInternal(ctx *util.Context, node *kubeoneapi.HostConfig
logger := ctx.Logger.WithField("node", node.PublicAddress)
logger.Infof("Waiting %s to ensure main control plane components are up…", sleepTime)
time.Sleep(sleepTime)
logger.Info("Joining control plane node")

_, _, err := ctx.Runner.Run(`
if [[ -f /etc/kubernetes/kubelet.conf ]]; then exit 0; fi
Expand Down
7 changes: 6 additions & 1 deletion pkg/installer/installation/kubeadm_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,13 @@ import (
func generateKubeadm(ctx *util.Context) error {
ctx.Logger.Infoln("Generating kubeadm config file…")

kadm, err := kubeadm.New(ctx.Cluster.Versions.Kubernetes)
if err != nil {
return errors.Wrap(err, "failed to init kubeadm")
}

for idx := range ctx.Cluster.Hosts {
kubeadm, err := kubeadm.Config(ctx, ctx.Cluster.Hosts[idx])
kubeadm, err := kadm.Config(ctx, ctx.Cluster.Hosts[idx])
if err != nil {
return errors.Wrap(err, "failed to create kubeadm configuration")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,31 +17,28 @@ limitations under the License.
package kubeadm

import (
"github.com/pkg/errors"

kubeoneapi "github.com/kubermatic/kubeone/pkg/apis/kubeone"
"github.com/kubermatic/kubeone/pkg/templates"
"github.com/kubermatic/kubeone/pkg/templates/kubeadm/v1beta1"
"github.com/kubermatic/kubeone/pkg/util"
)

// Config returns appropriate version of kubeadm config as YAML
func Config(ctx *util.Context, instance kubeoneapi.HostConfig) (string, error) {
cluster := ctx.Cluster
masterNodes := cluster.Hosts
if len(masterNodes) == 0 {
return "", errors.New("cluster does not contain at least one master node")
}
type kubeadmv1beta1 struct {
}

configs, err := v1beta1.NewConfig(ctx, instance)
func (*kubeadmv1beta1) Config(ctx *util.Context, instance kubeoneapi.HostConfig) (string, error) {
config, err := v1beta1.NewConfig(ctx, instance)
if err != nil {
return "", err
}

//TODO: Change KubernetesToYAML to accept runtime.Object instead of empty interface
var kubernetesToYAMLInput []interface{}
for _, config := range configs {
kubernetesToYAMLInput = append(kubernetesToYAMLInput, interface{}(config))
}
return templates.KubernetesToYAML(kubernetesToYAMLInput)
return templates.KubernetesToYAML(config)
}

func (*kubeadmv1beta1) UpgradeLeaderCMD() string {
return "kubeadm upgrade apply"
}

func (*kubeadmv1beta1) UpgradeFollowerCMD() string {
return "kubeadm upgrade node experimental-control-plane"
}
36 changes: 36 additions & 0 deletions pkg/templates/kubeadm/kubeadmv1beta2.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
Copyright 2019 The KubeOne Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package kubeadm

import (
"github.com/pkg/errors"

kubeoneapi "github.com/kubermatic/kubeone/pkg/apis/kubeone"
"github.com/kubermatic/kubeone/pkg/util"
)

type kubeadmv1beta2 struct {
kubeadmv1beta1
}

func (*kubeadmv1beta2) Config(ctx *util.Context, instance kubeoneapi.HostConfig) (string, error) {
return "", errors.New("kubeadm v1beta2 not implemented")
}

func (*kubeadmv1beta2) UpgradeFollowerCMD() string {
return "kubeadm upgrade node control-plane"
}
66 changes: 66 additions & 0 deletions pkg/templates/kubeadm/provider.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
Copyright 2019 The KubeOne Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package kubeadm

import (
"github.com/Masterminds/semver"
"github.com/pkg/errors"

kubeoneapi "github.com/kubermatic/kubeone/pkg/apis/kubeone"
"github.com/kubermatic/kubeone/pkg/util"
)

var (
v13x = mustParseConstraint("1.13.x")
v14x = mustParseConstraint("1.14.x")
v15x = mustParseConstraint("1.15.x")
)

// KubeADM interface abstract differences between different kubeadm versions
type KubeADM interface {
Config(ctx *util.Context, instance kubeoneapi.HostConfig) (string, error)
UpgradeLeaderCMD() string
UpgradeFollowerCMD() string
}

// New constructor
func New(ver string) (KubeADM, error) {
sver, err := semver.NewVersion(ver)
if err != nil {
return nil, errors.Wrap(err, "failed to parse version")
}
switch {
case v13x.Check(sver):
return &kubeadmv1beta1{}, nil
case v14x.Check(sver):
return &kubeadmv1beta1{}, nil
case v15x.Check(sver):
return &kubeadmv1beta2{}, nil
}

// By default use latest known kubeadm API version
return &kubeadmv1beta2{}, nil
}

func mustParseConstraint(constraint string) *semver.Constraints {
c, err := semver.NewConstraint(constraint)
if err != nil {
panic(err)
}

return c
}
14 changes: 6 additions & 8 deletions pkg/templates/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@ package templates

import (
"bytes"
"strings"

"github.com/ghodss/yaml"
"github.com/pkg/errors"

"k8s.io/apimachinery/pkg/runtime"
)

// KubernetesToYAML properly encodes a list of resources as YAML.
Expand All @@ -31,7 +32,7 @@ import (
// This function takes a slice of items to support creating a
// multi-document YAML string (separated with "---" between each
// item).
func KubernetesToYAML(data []interface{}) (string, error) {
func KubernetesToYAML(data []runtime.Object) (string, error) {
var buffer bytes.Buffer

for _, item := range data {
Expand All @@ -40,18 +41,15 @@ func KubernetesToYAML(data []interface{}) (string, error) {
err error
)

if str, ok := item.(string); ok {
encodedItem = []byte(strings.TrimSpace(str))
} else {
encodedItem, err = yaml.Marshal(item)
}

encodedItem, err = yaml.Marshal(item)
if err != nil {
return "", errors.Wrap(err, "failed to marshal item")
}

if _, err := buffer.Write(encodedItem); err != nil {
return "", errors.Wrap(err, "failed to write into buffer")
}

if _, err := buffer.WriteString("\n---\n"); err != nil {
return "", errors.Wrap(err, "failed to write into buffer")
}
Expand Down
8 changes: 6 additions & 2 deletions pkg/upgrader/upgrade/kubeadm_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,17 @@ import (
)

func generateKubeadmConfig(ctx *util.Context, node kubeoneapi.HostConfig) error {
kubeadmConf, err := kubeadm.Config(ctx, node)
kadm, err := kubeadm.New(ctx.Cluster.Versions.Kubernetes)
if err != nil {
return errors.Wrap(err, "failed to init kubeadm")
}

kubeadmConf, err := kadm.Config(ctx, node)
if err != nil {
return errors.Wrap(err, "failed to create kubeadm configuration")
}

ctx.Configuration.AddFile("cfg/master_0.yaml", kubeadmConf)

return nil
}

Expand Down
28 changes: 22 additions & 6 deletions pkg/upgrader/upgrade/kubeadm_upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,30 +17,46 @@ limitations under the License.
package upgrade

import (
"github.com/pkg/errors"

"github.com/kubermatic/kubeone/pkg/templates/kubeadm"
"github.com/kubermatic/kubeone/pkg/util"
)

const (
kubeadmUpgradeLeaderCommand = `
sudo kubeadm upgrade apply \
sudo {{ .KUBEADM_UPGRADE }} \
--config=./{{ .WORK_DIR }}/cfg/master_0.yaml \
-y {{ .VERSION }}
`
kubeadmUpgradeFollowerCommand = `
sudo kubeadm upgrade node experimental-control-plane
sudo {{ .KUBEADM_UPGRADE }}
`
)

func upgradeLeaderControlPlane(ctx *util.Context) error {
_, _, err := ctx.Runner.Run(kubeadmUpgradeLeaderCommand, util.TemplateVariables{
"VERSION": ctx.Cluster.Versions.Kubernetes,
"WORK_DIR": ctx.WorkDir,
kadm, err := kubeadm.New(ctx.Cluster.Versions.Kubernetes)
if err != nil {
return errors.Wrap(err, "failed to init kubeadm")
}

_, _, err = ctx.Runner.Run(kubeadmUpgradeLeaderCommand, util.TemplateVariables{
"KUBEADM_UPGRADE": kadm.UpgradeLeaderCMD(),
"VERSION": ctx.Cluster.Versions.Kubernetes,
"WORK_DIR": ctx.WorkDir,
})

return err
}

func upgradeFollowerControlPlane(ctx *util.Context) error {
_, _, err := ctx.Runner.Run(kubeadmUpgradeFollowerCommand, util.TemplateVariables{})
kadm, err := kubeadm.New(ctx.Cluster.Versions.Kubernetes)
if err != nil {
return errors.Wrap(err, "failed to init kubadm")
}

_, _, err = ctx.Runner.Run(kubeadmUpgradeFollowerCommand, util.TemplateVariables{
"KUBEADM_UPGRADE": kadm.UpgradeFollowerCMD(),
})
return err
}

0 comments on commit 586cca2

Please sign in to comment.