Skip to content

Commit

Permalink
gets the correct version of kubernetes client for DaemonSet and State…
Browse files Browse the repository at this point in the history
…fulSet History and Rollback and updates test-cmd for new versions
  • Loading branch information
Kenneth Owens committed Oct 11, 2017
1 parent a66d93b commit 9549174
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 45 deletions.
6 changes: 3 additions & 3 deletions hack/make-rules/test-cmd-util.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1350,7 +1350,7 @@ run_kubectl_get_tests() {
kube::test::if_has_string "${output_message}" "/api/v1/namespaces/default/pods 200 OK"
kube::test::if_has_string "${output_message}" "/api/v1/namespaces/default/replicationcontrollers 200 OK"
kube::test::if_has_string "${output_message}" "/api/v1/namespaces/default/services 200 OK"
kube::test::if_has_string "${output_message}" "/apis/apps/v1beta1/namespaces/default/statefulsets 200 OK"
kube::test::if_has_string "${output_message}" "/apis/apps/v1/namespaces/default/statefulsets 200 OK"
kube::test::if_has_string "${output_message}" "/apis/autoscaling/v1/namespaces/default/horizontalpodautoscalers 200"
kube::test::if_has_string "${output_message}" "/apis/batch/v1/namespaces/default/jobs 200 OK"
kube::test::if_has_string "${output_message}" "/apis/extensions/v1beta1/namespaces/default/deployments 200 OK"
Expand Down Expand Up @@ -2698,7 +2698,7 @@ run_deployment_tests() {
output_message=$(kubectl get deployment.extensions -o=jsonpath='{.items[0].apiVersion}' 2>&1 "${kube_flags[@]}")
kube::test::if_has_string "${output_message}" 'extensions/v1beta1'
output_message=$(kubectl get deployment.apps -o=jsonpath='{.items[0].apiVersion}' 2>&1 "${kube_flags[@]}")
kube::test::if_has_string "${output_message}" 'apps/v1beta1'
kube::test::if_has_string "${output_message}" 'apps/v1'
# Clean up
kubectl delete deployment test-nginx-extensions "${kube_flags[@]}"

Expand All @@ -2713,7 +2713,7 @@ run_deployment_tests() {
output_message=$(kubectl get deployment.extensions -o=jsonpath='{.items[0].apiVersion}' 2>&1 "${kube_flags[@]}")
kube::test::if_has_string "${output_message}" 'extensions/v1beta1'
output_message=$(kubectl get deployment.apps -o=jsonpath='{.items[0].apiVersion}' 2>&1 "${kube_flags[@]}")
kube::test::if_has_string "${output_message}" 'apps/v1beta1'
kube::test::if_has_string "${output_message}" 'apps/v1'
# Describe command (resource only) should print detailed information
kube::test::describe_resource_assert rs "Name:" "Pod Template:" "Labels:" "Selector:" "Controlled By" "Replicas:" "Pods Status:" "Volumes:"
# Describe command (resource only) should print detailed information
Expand Down
1 change: 1 addition & 0 deletions pkg/kubectl/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ go_library(
"//vendor/k8s.io/apimachinery/pkg/util/validation:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/watch:go_default_library",
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
"//vendor/k8s.io/client-go/kubernetes/typed/apps/v1beta1:go_default_library",
"//vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1:go_default_library",
"//vendor/k8s.io/client-go/rest:go_default_library",
Expand Down
6 changes: 4 additions & 2 deletions pkg/kubectl/cmd/util/factory_object_mapping.go
Original file line number Diff line number Diff line change
Expand Up @@ -330,19 +330,21 @@ func (f *ring1Factory) Reaper(mapping *meta.RESTMapping) (kubectl.Reaper, error)
func (f *ring1Factory) HistoryViewer(mapping *meta.RESTMapping) (kubectl.HistoryViewer, error) {
mappingVersion := mapping.GroupVersionKind.GroupVersion()
clientset, err := f.clientAccessFactory.ClientSetForVersion(&mappingVersion)
external, err := f.clientAccessFactory.KubernetesClientSet()
if err != nil {
return nil, err
}
return kubectl.HistoryViewerFor(mapping.GroupVersionKind.GroupKind(), clientset)
return kubectl.HistoryViewerFor(mapping.GroupVersionKind.GroupKind(), clientset, external)
}

func (f *ring1Factory) Rollbacker(mapping *meta.RESTMapping) (kubectl.Rollbacker, error) {
mappingVersion := mapping.GroupVersionKind.GroupVersion()
clientset, err := f.clientAccessFactory.ClientSetForVersion(&mappingVersion)
external, err := f.clientAccessFactory.KubernetesClientSet()
if err != nil {
return nil, err
}
return kubectl.RollbackerFor(mapping.GroupVersionKind.GroupKind(), clientset)
return kubectl.RollbackerFor(mapping.GroupVersionKind.GroupKind(), clientset, external)
}

func (f *ring1Factory) StatusViewer(mapping *meta.RESTMapping) (kubectl.StatusViewer, error) {
Expand Down
36 changes: 18 additions & 18 deletions pkg/kubectl/history.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,14 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/json"
"k8s.io/apimachinery/pkg/util/strategicpatch"
"k8s.io/client-go/kubernetes"
clientappsv1beta1 "k8s.io/client-go/kubernetes/typed/apps/v1beta1"
clientextensionsv1beta1 "k8s.io/client-go/kubernetes/typed/extensions/v1beta1"
"k8s.io/kubernetes/pkg/api"
apiv1 "k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/apis/apps"
"k8s.io/kubernetes/pkg/apis/extensions"
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
deploymentutil "k8s.io/kubernetes/pkg/controller/deployment/util"
sliceutil "k8s.io/kubernetes/pkg/kubectl/util/slice"
printersinternal "k8s.io/kubernetes/pkg/printers/internalversion"
Expand All @@ -52,26 +53,27 @@ type HistoryViewer interface {
ViewHistory(namespace, name string, revision int64) (string, error)
}

func HistoryViewerFor(kind schema.GroupKind, c clientset.Interface) (HistoryViewer, error) {
func HistoryViewerFor(kind schema.GroupKind, c internalclientset.Interface, ec kubernetes.Interface) (HistoryViewer, error) {
switch kind {
case extensions.Kind("Deployment"), apps.Kind("Deployment"):
return &DeploymentHistoryViewer{c}, nil
return &DeploymentHistoryViewer{c, ec}, nil
case apps.Kind("StatefulSet"):
return &StatefulSetHistoryViewer{c}, nil
return &StatefulSetHistoryViewer{c, ec}, nil
case extensions.Kind("DaemonSet"), apps.Kind("DaemonSet"):
return &DaemonSetHistoryViewer{c}, nil
return &DaemonSetHistoryViewer{c, ec}, nil
}
return nil, fmt.Errorf("no history viewer has been implemented for %q", kind)
}

type DeploymentHistoryViewer struct {
c clientset.Interface
ic internalclientset.Interface
ec kubernetes.Interface
}

// ViewHistory returns a revision-to-replicaset map as the revision history of a deployment
// TODO: this should be a describer
func (h *DeploymentHistoryViewer) ViewHistory(namespace, name string, revision int64) (string, error) {
versionedExtensionsClient := versionedExtensionsClientV1beta1(h.c)
versionedExtensionsClient := h.ec.ExtensionsV1beta1()
deployment, err := versionedExtensionsClient.Deployments(namespace).Get(name, metav1.GetOptions{})
if err != nil {
return "", fmt.Errorf("failed to retrieve deployment %s: %v", name, err)
Expand Down Expand Up @@ -147,14 +149,15 @@ func printTemplate(template *v1.PodTemplateSpec) (string, error) {
}

type DaemonSetHistoryViewer struct {
c clientset.Interface
id internalclientset.Interface
ec kubernetes.Interface
}

// ViewHistory returns a revision-to-history map as the revision history of a deployment
// TODO: this should be a describer
func (h *DaemonSetHistoryViewer) ViewHistory(namespace, name string, revision int64) (string, error) {
versionedAppsClient := versionedAppsClientV1beta1(h.c)
versionedExtensionsClient := versionedExtensionsClientV1beta1(h.c)
versionedAppsClient := h.ec.AppsV1beta1()
versionedExtensionsClient := h.ec.ExtensionsV1beta1()
versionedObj, allHistory, err := controlledHistories(versionedAppsClient, versionedExtensionsClient, namespace, name, "DaemonSet")
if err != nil {
return "", fmt.Errorf("unable to find history controlled by DaemonSet %s: %v", name, err)
Expand Down Expand Up @@ -211,7 +214,8 @@ func (h *DaemonSetHistoryViewer) ViewHistory(namespace, name string, revision in
}

type StatefulSetHistoryViewer struct {
c clientset.Interface
ic internalclientset.Interface
ec kubernetes.Interface
}

func getOwner(revision apps.ControllerRevision) *metav1.OwnerReference {
Expand All @@ -230,15 +234,15 @@ func getOwner(revision apps.ControllerRevision) *metav1.OwnerReference {
// TODO: needs to implement detailed revision view
func (h *StatefulSetHistoryViewer) ViewHistory(namespace, name string, revision int64) (string, error) {

sts, err := h.c.Apps().StatefulSets(namespace).Get(name, metav1.GetOptions{})
sts, err := h.ic.Apps().StatefulSets(namespace).Get(name, metav1.GetOptions{})
if err != nil {
return "", fmt.Errorf("failed to retrieve statefulset %s", err)
}
selector, err := metav1.LabelSelectorAsSelector(sts.Spec.Selector)
if err != nil {
return "", fmt.Errorf("failed to retrieve statefulset history %s", err)
}
revisions, err := h.c.Apps().ControllerRevisions(namespace).List(metav1.ListOptions{LabelSelector: selector.String()})
revisions, err := h.ic.Apps().ControllerRevisions(namespace).List(metav1.ListOptions{LabelSelector: selector.String()})
if err != nil {
return "", fmt.Errorf("failed to retrieve statefulset history %s", err)
}
Expand Down Expand Up @@ -311,11 +315,7 @@ func controlledHistories(apps clientappsv1beta1.AppsV1beta1Interface, extensions

// applyHistory returns a specific revision of DaemonSet by applying the given history to a copy of the given DaemonSet
func applyHistory(ds *extensionsv1beta1.DaemonSet, history *appsv1beta1.ControllerRevision) (*extensionsv1beta1.DaemonSet, error) {
obj, err := api.Scheme.New(ds.GroupVersionKind())
if err != nil {
return nil, err
}
clone := obj.(*extensionsv1beta1.DaemonSet)
clone := ds.DeepCopy()
cloneBytes, err := json.Marshal(clone)
if err != nil {
return nil, err
Expand Down
46 changes: 24 additions & 22 deletions pkg/kubectl/rollback.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/kubernetes"
"k8s.io/kubernetes/pkg/api"
apiv1 "k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/apis/apps"
Expand All @@ -54,20 +55,21 @@ type Rollbacker interface {
Rollback(obj runtime.Object, updatedAnnotations map[string]string, toRevision int64, dryRun bool) (string, error)
}

func RollbackerFor(kind schema.GroupKind, c clientset.Interface) (Rollbacker, error) {
func RollbackerFor(kind schema.GroupKind, c clientset.Interface, e kubernetes.Interface) (Rollbacker, error) {
switch kind {
case extensions.Kind("Deployment"), apps.Kind("Deployment"):
return &DeploymentRollbacker{c}, nil
return &DeploymentRollbacker{c, e}, nil
case extensions.Kind("DaemonSet"), apps.Kind("DaemonSet"):
return &DaemonSetRollbacker{c}, nil
return &DaemonSetRollbacker{c, e}, nil
case apps.Kind("StatefulSet"):
return &StatefulSetRollbacker{c}, nil
return &StatefulSetRollbacker{c, e}, nil
}
return nil, fmt.Errorf("no rollbacker has been implemented for %q", kind)
}

type DeploymentRollbacker struct {
c clientset.Interface
ic clientset.Interface
ec kubernetes.Interface
}

func (r *DeploymentRollbacker) Rollback(obj runtime.Object, updatedAnnotations map[string]string, toRevision int64, dryRun bool) (string, error) {
Expand All @@ -76,7 +78,7 @@ func (r *DeploymentRollbacker) Rollback(obj runtime.Object, updatedAnnotations m
return "", fmt.Errorf("passed object is not a Deployment: %#v", obj)
}
if dryRun {
return simpleDryRun(d, r.c, toRevision)
return simpleDryRun(d, r.ec, toRevision)
}
if d.Spec.Paused {
return "", fmt.Errorf("you cannot rollback a paused deployment; resume it first with 'kubectl rollout resume deployment/%s' and try again", d.Name)
Expand All @@ -91,16 +93,16 @@ func (r *DeploymentRollbacker) Rollback(obj runtime.Object, updatedAnnotations m
result := ""

// Get current events
events, err := r.c.Core().Events(d.Namespace).List(metav1.ListOptions{})
events, err := r.ic.Core().Events(d.Namespace).List(metav1.ListOptions{})
if err != nil {
return result, err
}
// Do the rollback
if err := r.c.Extensions().Deployments(d.Namespace).Rollback(deploymentRollback); err != nil {
if err := r.ic.Extensions().Deployments(d.Namespace).Rollback(deploymentRollback); err != nil {
return result, err
}
// Watch for the changes of events
watch, err := r.c.Core().Events(d.Namespace).Watch(metav1.ListOptions{Watch: true, ResourceVersion: events.ResourceVersion})
watch, err := r.ic.Core().Events(d.Namespace).Watch(metav1.ListOptions{Watch: true, ResourceVersion: events.ResourceVersion})
if err != nil {
return result, err
}
Expand Down Expand Up @@ -149,13 +151,13 @@ func isRollbackEvent(e *api.Event) (bool, string) {
return false, ""
}

func simpleDryRun(deployment *extensions.Deployment, c clientset.Interface, toRevision int64) (string, error) {
func simpleDryRun(deployment *extensions.Deployment, c kubernetes.Interface, toRevision int64) (string, error) {
externalDeployment := &externalextensions.Deployment{}
if err := api.Scheme.Convert(deployment, externalDeployment, nil); err != nil {
return "", fmt.Errorf("failed to convert deployment, %v", err)
}
versionedExtensionsClient := versionedExtensionsClientV1beta1(c)
_, allOldRSs, newRS, err := deploymentutil.GetAllReplicaSets(externalDeployment, versionedExtensionsClient)

_, allOldRSs, newRS, err := deploymentutil.GetAllReplicaSets(externalDeployment, c.ExtensionsV1beta1())
if err != nil {
return "", fmt.Errorf("failed to retrieve replica sets from deployment %s: %v", deployment.Name, err)
}
Expand Down Expand Up @@ -212,7 +214,8 @@ func simpleDryRun(deployment *extensions.Deployment, c clientset.Interface, toRe
}

type DaemonSetRollbacker struct {
c clientset.Interface
ic clientset.Interface
ec kubernetes.Interface
}

func (r *DaemonSetRollbacker) Rollback(obj runtime.Object, updatedAnnotations map[string]string, toRevision int64, dryRun bool) (string, error) {
Expand All @@ -224,9 +227,8 @@ func (r *DaemonSetRollbacker) Rollback(obj runtime.Object, updatedAnnotations ma
if !ok {
return "", fmt.Errorf("passed object is not a DaemonSet: %#v", obj)
}
versionedAppsClient := versionedAppsClientV1beta1(r.c)
versionedExtensionsClient := versionedExtensionsClientV1beta1(r.c)
versionedObj, allHistory, err := controlledHistories(versionedAppsClient, versionedExtensionsClient, ds.Namespace, ds.Name, "DaemonSet")

versionedObj, allHistory, err := controlledHistories(r.ec.AppsV1beta1(), r.ec.ExtensionsV1beta1(), ds.Namespace, ds.Name, "DaemonSet")
if err != nil {
return "", fmt.Errorf("unable to find history controlled by DaemonSet %s: %v", ds.Name, err)
}
Expand Down Expand Up @@ -262,15 +264,16 @@ func (r *DaemonSetRollbacker) Rollback(obj runtime.Object, updatedAnnotations ma
}

// Restore revision
if _, err = versionedExtensionsClient.DaemonSets(ds.Namespace).Patch(ds.Name, types.StrategicMergePatchType, toHistory.Data.Raw); err != nil {
if _, err = r.ec.ExtensionsV1beta1().DaemonSets(ds.Namespace).Patch(ds.Name, types.StrategicMergePatchType, toHistory.Data.Raw); err != nil {
return "", fmt.Errorf("failed restoring revision %d: %v", toRevision, err)
}

return rollbackSuccess, nil
}

type StatefulSetRollbacker struct {
c clientset.Interface
ic clientset.Interface
ec kubernetes.Interface
}

// toRevision is a non-negative integer, with 0 being reserved to indicate rolling back to previous configuration
Expand All @@ -283,9 +286,8 @@ func (r *StatefulSetRollbacker) Rollback(obj runtime.Object, updatedAnnotations
if !ok {
return "", fmt.Errorf("passed object is not a StatefulSet: %#v", obj)
}
versionedAppsClient := versionedAppsClientV1beta1(r.c)
versionedExtensionsClient := versionedExtensionsClientV1beta1(r.c)
versionedObj, allHistory, err := controlledHistories(versionedAppsClient, versionedExtensionsClient, ss.Namespace, ss.Name, "StatefulSet")

versionedObj, allHistory, err := controlledHistories(r.ec.AppsV1beta1(), r.ec.ExtensionsV1beta1(), ss.Namespace, ss.Name, "StatefulSet")
if err != nil {
return "", fmt.Errorf("unable to find history controlled by StatefulSet %s: %v", ss.Name, err)
}
Expand Down Expand Up @@ -322,7 +324,7 @@ func (r *StatefulSetRollbacker) Rollback(obj runtime.Object, updatedAnnotations
}

// Restore revision
if _, err = versionedAppsClient.StatefulSets(ss.Namespace).Patch(ss.Name, types.StrategicMergePatchType, toHistory.Data.Raw); err != nil {
if _, err = r.ec.AppsV1beta1().StatefulSets(ss.Namespace).Patch(ss.Name, types.StrategicMergePatchType, toHistory.Data.Raw); err != nil {
return "", fmt.Errorf("failed restoring revision %d: %v", toRevision, err)
}

Expand Down

0 comments on commit 9549174

Please sign in to comment.