Merge pull request #63930 from liztio/kubeadm-init-diff

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

Implement `kubeadm init diff`

**What this PR does / why we need it**:

Some users want to see the changes `kubeadm` woulda apply before actually running `kubeadm upgrade apply`. This shows the changes that will be made to the static pod manifests before applying them. This is a narrower case than `kubeadm upgrade apply --dry-run`, which specifically focuses on the static pod manifests.

**Which issue(s) this PR fixes**:
Part of [kubeadm/489](https://github.com/kubernetes/kubeadm/issues/489#issuecomment-388974795)

**Special notes for your reviewer**:

**Release note**:

```release-note
adds the `kubeadm upgrade diff` command to show how static pod manifests will be changed by an upgrade.
```
pull/8/head
Kubernetes Submit Queue 2018-05-17 00:28:26 -07:00 committed by GitHub
commit 2fda6e5e7a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 151 additions and 0 deletions

View File

@ -5,6 +5,7 @@ go_library(
srcs = [
"apply.go",
"common.go",
"diff.go",
"plan.go",
"upgrade.go",
],
@ -29,7 +30,9 @@ go_library(
"//cmd/kubeadm/app/util/kubeconfig:go_default_library",
"//pkg/util/version:go_default_library",
"//vendor/github.com/golang/glog:go_default_library",
"//vendor/github.com/pmezard/go-difflib/difflib:go_default_library",
"//vendor/github.com/spf13/cobra:go_default_library",
"//vendor/k8s.io/api/core/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//vendor/k8s.io/client-go/discovery/fake:go_default_library",
"//vendor/k8s.io/client-go/kubernetes:go_default_library",

View File

@ -0,0 +1,139 @@
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package upgrade
import (
"io/ioutil"
"os"
"github.com/golang/glog"
"github.com/pmezard/go-difflib/difflib"
"github.com/spf13/cobra"
corev1 "k8s.io/api/core/v1"
kubeadmv1alpha2 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha2"
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
"k8s.io/kubernetes/cmd/kubeadm/app/phases/controlplane"
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config"
"k8s.io/kubernetes/pkg/util/version"
)
type diffFlags struct {
apiServerManifestPath string
controllerManagerManifestPath string
schedulerManifestPath string
newK8sVersionStr string
contextLines int
parent *cmdUpgradeFlags
}
var (
defaultAPIServerManifestPath = constants.GetStaticPodFilepath(constants.KubeAPIServer, constants.GetStaticPodDirectory())
defaultControllerManagerManifestPath = constants.GetStaticPodFilepath(constants.KubeControllerManager, constants.GetStaticPodDirectory())
defaultSchedulerManifestPath = constants.GetStaticPodFilepath(constants.KubeScheduler, constants.GetStaticPodDirectory())
)
// NewCmdDiff returns the cobra command for `kubeadm upgrade diff`
func NewCmdDiff(parentflags *cmdUpgradeFlags) *cobra.Command {
flags := &diffFlags{
parent: parentflags,
}
cmd := &cobra.Command{
Use: "diff [version]",
Short: "Show what differences would be applied to existing static pod manifests. See also: kubeadm upgrade apply --dry-run",
Run: func(cmd *cobra.Command, args []string) {
kubeadmutil.CheckErr(runDiff(flags, args))
},
}
cmd.Flags().StringVar(&flags.apiServerManifestPath, "api-server-manifest", defaultAPIServerManifestPath, "path to API server manifest")
cmd.Flags().StringVar(&flags.controllerManagerManifestPath, "controller-manager-manifest", defaultControllerManagerManifestPath, "path to controller manifest")
cmd.Flags().StringVar(&flags.schedulerManifestPath, "scheduler-manifest", defaultSchedulerManifestPath, "path to scheduler manifest")
cmd.Flags().IntVarP(&flags.contextLines, "context-lines", "c", 3, "How many lines of context in the diff")
return cmd
}
func runDiff(flags *diffFlags, args []string) error {
// If the version is specified in config file, pick up that value.
glog.V(1).Infof("fetching configuration from file", flags.parent.cfgPath)
cfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(flags.parent.cfgPath, &kubeadmv1alpha2.MasterConfiguration{})
if err != nil {
return err
}
if cfg.KubernetesVersion != "" {
flags.newK8sVersionStr = cfg.KubernetesVersion
}
// If the new version is already specified in config file, version arg is optional.
if flags.newK8sVersionStr == "" {
if err := cmdutil.ValidateExactArgNumber(args, []string{"version"}); err != nil {
return err
}
}
// If option was specified in both args and config file, args will overwrite the config file.
if len(args) == 1 {
flags.newK8sVersionStr = args[0]
}
k8sVer, err := version.ParseSemantic(flags.newK8sVersionStr)
if err != nil {
return err
}
specs := controlplane.GetStaticPodSpecs(cfg, k8sVer)
for spec, pod := range specs {
var path string
switch spec {
case constants.KubeAPIServer:
path = flags.apiServerManifestPath
case constants.KubeControllerManager:
path = flags.controllerManagerManifestPath
case constants.KubeScheduler:
path = flags.schedulerManifestPath
default:
glog.Errorf("[diff] unknown spec %v", spec)
continue
}
newManifest, err := kubeadmutil.MarshalToYaml(&pod, corev1.SchemeGroupVersion)
if err != nil {
return err
}
existingManifest, err := ioutil.ReadFile(path)
if err != nil {
return err
}
// Populated and write out the diff
diff := difflib.UnifiedDiff{
A: difflib.SplitLines(string(existingManifest)),
B: difflib.SplitLines(string(newManifest)),
FromFile: path,
ToFile: "new manifest",
Context: flags.contextLines,
}
difflib.WriteUnifiedDiff(os.Stdout, diff)
}
return nil
}

View File

@ -71,6 +71,7 @@ func NewCmdUpgrade(out io.Writer) *cobra.Command {
cmd.AddCommand(NewCmdApply(flags))
cmd.AddCommand(NewCmdPlan(flags))
cmd.AddCommand(NewCmdDiff(flags))
return cmd
}

View File

@ -75,6 +75,7 @@ docs/admin/kubeadm_token_generate.md
docs/admin/kubeadm_token_list.md
docs/admin/kubeadm_upgrade.md
docs/admin/kubeadm_upgrade_apply.md
docs/admin/kubeadm_upgrade_diff.md
docs/admin/kubeadm_upgrade_plan.md
docs/admin/kubeadm_version.md
docs/admin/kubelet.md
@ -152,6 +153,7 @@ docs/man/man1/kubeadm-token-generate.1
docs/man/man1/kubeadm-token-list.1
docs/man/man1/kubeadm-token.1
docs/man/man1/kubeadm-upgrade-apply.1
docs/man/man1/kubeadm-upgrade-diff.1
docs/man/man1/kubeadm-upgrade-plan.1
docs/man/man1/kubeadm-upgrade.1
docs/man/man1/kubeadm-version.1

View File

@ -0,0 +1,3 @@
This file is autogenerated, but we've stopped checking such files into the
repository to reduce the need for rebases. Please run hack/generate-docs.sh to
populate this file.

View File

@ -0,0 +1,3 @@
This file is autogenerated, but we've stopped checking such files into the
repository to reduce the need for rebases. Please run hack/generate-docs.sh to
populate this file.