Skip to content

Commit

Permalink
Merge pull request #47 from veophi/rollout
Browse files Browse the repository at this point in the history
Bump dependencies to 1.22 & Add `pause`, `resume` and `approve` command for kruise rollout
  • Loading branch information
hantmac authored Apr 27, 2022
2 parents fe97756 + 0ca6904 commit d858e70
Show file tree
Hide file tree
Showing 17 changed files with 601 additions and 90 deletions.
8 changes: 7 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,16 @@ default: build

build: kubectl-kruise

kubectl-kruise:
kubectl-kruise: fmt vet
GO111MODULE=on CGO_ENABLED=0 go build -ldflags "$(LDFLAGS)" -o bin/kubectl-kruise cmd/plugin/main.go

test:
find . -iname '*.go' -type f | grep -v /vendor/ | xargs gofmt -l
GO111MODULE=on go test -v -race ./...
go vet ./...

fmt: ## Run go fmt against code.
go fmt ./...

vet: ## Run go vet against code.
go vet ./...
52 changes: 32 additions & 20 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,44 @@ module github.com/openkruise/kruise-tools
go 1.16

require (
github.com/go-logr/logr v0.2.1 // indirect
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6 // indirect
github.com/coreos/go-etcd v2.0.0+incompatible // indirect
github.com/cpuguy83/go-md2man v1.0.10 // indirect
github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0 // indirect
github.com/go-openapi/validate v0.19.5 // indirect
github.com/hashicorp/golang-lru v0.5.4 // indirect
github.com/lithammer/dedent v1.1.0
github.com/moby/term v0.0.0-20200312100748-672ec06f55cd
github.com/openkruise/kruise-api v0.10.0
github.com/moby/term v0.0.0-20210610120745-9d4ed1856297
github.com/openkruise/kruise-api v1.0.0
github.com/openkruise/rollouts v0.1.0
github.com/spf13/cobra v1.1.3
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.6.1
k8s.io/api v0.21.6
k8s.io/apimachinery v0.21.6
k8s.io/cli-runtime v0.21.6
k8s.io/client-go v0.21.6
k8s.io/component-base v0.21.6
k8s.io/klog/v2 v2.4.0
github.com/stretchr/testify v1.7.0
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8 // indirect
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77 // indirect
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738 // indirect
gotest.tools v2.2.0+incompatible // indirect
k8s.io/api v0.22.6
k8s.io/apimachinery v0.22.6
k8s.io/cli-runtime v0.22.6
k8s.io/client-go v0.22.6
k8s.io/component-base v0.22.6
k8s.io/klog v1.0.0 // indirect
k8s.io/klog/v2 v2.9.0
k8s.io/kubectl v0.21.6
sigs.k8s.io/controller-runtime v0.6.3
sigs.k8s.io/controller-runtime v0.10.3
sigs.k8s.io/structured-merge-diff/v3 v3.0.0 // indirect
)

// Replace to match K8s 1.20.12
replace (
k8s.io/api => k8s.io/api v0.20.12
k8s.io/apimachinery => k8s.io/apimachinery v0.20.12
k8s.io/cli-runtime => k8s.io/cli-runtime v0.20.12
k8s.io/client-go => k8s.io/client-go v0.20.12
k8s.io/code-generator => k8s.io/code-generator v0.20.12
k8s.io/component-base => k8s.io/component-base v0.20.12
k8s.io/component-helpers => k8s.io/component-helpers v0.20.12
k8s.io/kubectl => k8s.io/kubectl v0.20.12
k8s.io/metrics => k8s.io/metrics v0.20.12
k8s.io/api => k8s.io/api v0.22.6
k8s.io/apimachinery => k8s.io/apimachinery v0.22.6
k8s.io/cli-runtime => k8s.io/cli-runtime v0.22.6
k8s.io/client-go => k8s.io/client-go v0.22.6
k8s.io/code-generator => k8s.io/code-generator v0.22.6
k8s.io/component-base => k8s.io/component-base v0.22.6
k8s.io/component-helpers => k8s.io/component-helpers v0.22.6
k8s.io/kubectl => k8s.io/kubectl v0.22.6
k8s.io/metrics => k8s.io/metrics v0.22.6
)
317 changes: 261 additions & 56 deletions go.sum

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions pkg/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package api
import (
kruiseappsv1alpha1 "github.com/openkruise/kruise-api/apps/v1alpha1"
kruiseappsv1beta1 "github.com/openkruise/kruise-api/apps/v1beta1"
kruiserolloutsv1apha1 "github.com/openkruise/rollouts/api/v1alpha1"
apps "k8s.io/api/apps/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
Expand All @@ -38,6 +39,7 @@ func init() {
_ = clientgoscheme.AddToScheme(Scheme)
_ = kruiseappsv1alpha1.AddToScheme(Scheme)
_ = kruiseappsv1beta1.AddToScheme(Scheme)
_ = kruiserolloutsv1apha1.AddToScheme(Scheme)
}

func GetScheme() *runtime.Scheme {
Expand Down
4 changes: 2 additions & 2 deletions pkg/cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -437,8 +437,8 @@ func NewKubectlCommand(in io.Reader, out, err io.Writer) *cobra.Command {
}

cmds.AddCommand(alpha)
cmds.AddCommand(cmdconfig.NewCmdConfig(f, clientcmd.NewDefaultPathOptions(), ioStreams))
cmds.AddCommand(plugin.NewCmdPlugin(f, ioStreams))
cmds.AddCommand(cmdconfig.NewCmdConfig(clientcmd.NewDefaultPathOptions(), ioStreams))
cmds.AddCommand(plugin.NewCmdPlugin(ioStreams))
cmds.AddCommand(version.NewCmdVersion(f, ioStreams))
cmds.AddCommand(apiresources.NewCmdAPIVersions(f, ioStreams))
cmds.AddCommand(apiresources.NewCmdAPIResources(f, ioStreams))
Expand Down
2 changes: 2 additions & 0 deletions pkg/cmd/rollout/rollout.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ var (
* clonesets
* statefulsets.apps.kruise.io
* daemonsets.apps.kruise.io
* rollouts.rollouts.kruise.io
`)
)

Expand All @@ -67,6 +68,7 @@ func NewCmdRollout(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobr
cmd.AddCommand(NewCmdRolloutUndo(f, streams))
cmd.AddCommand(NewCmdRolloutStatus(f, streams))
cmd.AddCommand(NewCmdRolloutRestart(f, streams))
cmd.AddCommand(NewCmdRolloutApprove(f, streams))

return cmd
}
197 changes: 197 additions & 0 deletions pkg/cmd/rollout/rollout_approve.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
/*
Copyright 2021 The Kruise 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 rollout

import (
"fmt"

internalapi "github.com/openkruise/kruise-tools/pkg/api"
"github.com/openkruise/kruise-tools/pkg/cmd/util"
internalpolymorphichelpers "github.com/openkruise/kruise-tools/pkg/internal/polymorphichelpers"
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/types"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/cli-runtime/pkg/printers"
"k8s.io/cli-runtime/pkg/resource"
"k8s.io/kubectl/pkg/cmd/set"
cmdutil "k8s.io/kubectl/pkg/cmd/util"
"k8s.io/kubectl/pkg/scheme"
"k8s.io/kubectl/pkg/util/i18n"
"k8s.io/kubectl/pkg/util/templates"
)

// ApproveOptions is the start of the data required to perform the operation. As new fields are added, add them here instead of
// referencing the cmd.Flags()
type ApproveOptions struct {
PrintFlags *genericclioptions.PrintFlags
ToPrinter func(string) (printers.ResourcePrinter, error)

Resources []string

Builder func() *resource.Builder
Approver internalpolymorphichelpers.ObjectApproverFunc
Namespace string
EnforceNamespace bool

resource.FilenameOptions
genericclioptions.IOStreams
}

var (
ApproveLong = templates.LongDesc(`
Approve a resource which can be continued.
Paused resources will not be reconciled by a controller. By approving a
resource, we allow it to be continue to rollout.
Currently only kruise-rollouts support being approved.`)

ApproveExample = templates.Examples(`
# approve a kruise rollout resource named "rollout-demo" in "ns-demo" namespace
kubectl-kruise rollout approve rollout-demo -n ns-demo`)
)

// NewRolloutApproveOptions returns an initialized ApproveOptions instance
func NewRolloutApproveOptions(streams genericclioptions.IOStreams) *ApproveOptions {
return &ApproveOptions{
PrintFlags: genericclioptions.NewPrintFlags("approved").WithTypeSetter(internalapi.GetScheme()),
IOStreams: streams,
}
}

// NewCmdRolloutApprove returns a Command instance for 'rollout approve' sub command
func NewCmdRolloutApprove(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
o := NewRolloutApproveOptions(streams)

cmd := &cobra.Command{
Use: "approve RESOURCE",
DisableFlagsInUseLine: true,
Short: i18n.T("Approve a resource"),
Long: ApproveLong,
Example: ApproveExample,
Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(o.Complete(f, cmd, args))
cmdutil.CheckErr(o.Validate())
cmdutil.CheckErr(o.RunApprove())
},
}

usage := "identifying the resource to get from a server."
cmdutil.AddFilenameOptionFlags(cmd, &o.FilenameOptions, usage)
o.PrintFlags.AddFlags(cmd)
return cmd
}

// Complete completes all the required options
func (o *ApproveOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
o.Resources = args

o.Approver = internalpolymorphichelpers.ObjectApproverFn

var err error
o.Namespace, o.EnforceNamespace, err = f.ToRawKubeConfigLoader().Namespace()
if err != nil {
return err
}

o.ToPrinter = func(operation string) (printers.ResourcePrinter, error) {
o.PrintFlags.NamePrintFlags.Operation = operation
return o.PrintFlags.ToPrinter()
}

o.Builder = f.NewBuilder

return nil
}

func (o *ApproveOptions) Validate() error {
if len(o.Resources) == 0 && cmdutil.IsFilenameSliceEmpty(o.Filenames, o.Kustomize) {
return fmt.Errorf("required resource not specified")
}
return nil
}

// RunApprove performs the execution of 'rollout approve' sub command
func (o ApproveOptions) RunApprove() error {
r := o.Builder().
WithScheme(internalapi.GetScheme(), scheme.Scheme.PrioritizedVersionsAllGroups()...).
NamespaceParam(o.Namespace).DefaultNamespace().
FilenameParam(o.EnforceNamespace, &o.FilenameOptions).
ResourceTypeOrNameArgs(true, o.Resources...).
ContinueOnError().
Latest().
Flatten().
Do()
if err := r.Err(); err != nil {
return err
}

allErrs := []error{}
infos, err := r.Infos()
if err != nil {
// restore previous command behavior where
// an error caused by retrieving infos due to
// at least a single broken object did not result
// in an immediate return, but rather an overall
// aggregation of errors.
allErrs = append(allErrs, err)
}

for _, patch := range set.CalculatePatches(infos, scheme.DefaultJSONEncoder(), set.PatchFn(o.Approver)) {
info := patch.Info

if patch.Err != nil {
resourceString := info.Mapping.Resource.Resource
if len(info.Mapping.Resource.Group) > 0 {
resourceString = resourceString + "." + info.Mapping.Resource.Group
}
allErrs = append(allErrs, fmt.Errorf("error: %s %q %v", resourceString, info.Name, patch.Err))
continue
}

if string(patch.Patch) == "{}" || len(patch.Patch) == 0 {
printer, err := o.ToPrinter("already approved")
if err != nil {
allErrs = append(allErrs, err)
continue
}
if err = printer.PrintObj(info.Object, o.Out); err != nil {
allErrs = append(allErrs, err)
}
continue
}

obj, err := util.PatchSubResource(info.Client, info.Mapping.Resource.Resource, "status", info.Namespace, info.Name, info.Namespaced(), types.MergePatchType, patch.Patch, nil)
if err != nil {
allErrs = append(allErrs, fmt.Errorf("failed to patch: %v", err))
continue
}

info.Refresh(obj, true)
printer, err := o.ToPrinter("approved")
if err != nil {
allErrs = append(allErrs, err)
continue
}
if err = printer.PrintObj(info.Object, o.Out); err != nil {
allErrs = append(allErrs, err)
}
}

return utilerrors.NewAggregate(allErrs)
}
5 changes: 3 additions & 2 deletions pkg/cmd/rollout/rollout_pause.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,13 @@ var (
Paused resources will not be reconciled by a controller.
Use "kubectl rollout resume" to resume a paused resource.
Currently deployments, clonesets support being paused.`)
Currently deployments, clonesets, rollouts support being paused.`)

pauseExample = templates.Examples(`
# Mark the nginx deployment as paused. Any current state of
# the deployment will continue its function, new updates to the deployment will not
# have an effect as long as the deployment is paused.
kubectl-kruise rollout pause deployment/nginx`)
)

Expand All @@ -73,7 +74,7 @@ func NewCmdRolloutPause(f cmdutil.Factory, streams genericclioptions.IOStreams)
IOStreams: streams,
}

validArgs := []string{"deployment", "cloneset"}
validArgs := []string{"deployment", "cloneset", "rollout"}

cmd := &cobra.Command{
Use: "pause RESOURCE",
Expand Down
5 changes: 3 additions & 2 deletions pkg/cmd/rollout/rollout_resume.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,9 @@ var (
Currently deployments, cloneset support being resumed.`)

resumeExample = templates.Examples(`
# Resume an already paused deployment
# Resume an already paused rollout/cloneset/deployment resource
kubectl-kruise rollout resume rollout/nginx
kubectl-kruise rollout resume cloneset/nginx
kubectl-kruise rollout resume deployment/nginx`)
)
Expand All @@ -79,7 +80,7 @@ func NewRolloutResumeOptions(streams genericclioptions.IOStreams) *ResumeOptions
func NewCmdRolloutResume(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
o := NewRolloutResumeOptions(streams)

validArgs := []string{"deployment", "cloneset"}
validArgs := []string{"deployment", "cloneset", "rollout"}

cmd := &cobra.Command{
Use: "resume RESOURCE",
Expand Down
2 changes: 1 addition & 1 deletion pkg/cmd/set/set_env.go
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ func (o *EnvOptions) Validate() error {

// RunEnv contains all the necessary functionality for the OpenShift cli env command
func (o *EnvOptions) RunEnv() error {
env, remove, err := envutil.ParseEnv(append(o.EnvParams, o.envArgs...), o.In)
env, remove, _, err := envutil.ParseEnv(append(o.EnvParams, o.envArgs...), o.In)

if err != nil {
return err
Expand Down
Loading

0 comments on commit d858e70

Please sign in to comment.