Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 2c27df7

Browse files
committedJul 26, 2018
update idle command
1 parent 70c7679 commit 2c27df7

File tree

2 files changed

+62
-49
lines changed

2 files changed

+62
-49
lines changed
 

Diff for: ‎pkg/oc/cli/idle/idle.go

+59-46
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,18 @@ import (
1111
"github.com/spf13/cobra"
1212

1313
utilerrors "github.com/openshift/origin/pkg/util/errors"
14+
corev1 "k8s.io/api/core/v1"
1415
extensions "k8s.io/api/extensions/v1beta1"
1516
"k8s.io/apimachinery/pkg/api/meta"
1617
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1718
"k8s.io/apimachinery/pkg/runtime"
1819
"k8s.io/apimachinery/pkg/runtime/schema"
1920
"k8s.io/apimachinery/pkg/types"
2021
"k8s.io/apimachinery/pkg/util/strategicpatch"
22+
clientset "k8s.io/client-go/kubernetes"
2123
kextensionsclient "k8s.io/client-go/kubernetes/typed/extensions/v1beta1"
2224
"k8s.io/client-go/rest"
2325
"k8s.io/kubernetes/pkg/api/legacyscheme"
24-
kapi "k8s.io/kubernetes/pkg/apis/core"
25-
kinternalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
2626
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
2727
kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
2828
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
@@ -34,6 +34,7 @@ import (
3434
"github.com/openshift/origin/pkg/oc/util/ocscheme"
3535
unidlingapi "github.com/openshift/origin/pkg/unidling/api"
3636
utilunidling "github.com/openshift/origin/pkg/unidling/util"
37+
kinternalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
3738
)
3839

3940
var (
@@ -54,23 +55,26 @@ var (
5455
)
5556

5657
type IdleOptions struct {
57-
dryRun bool
58-
58+
dryRun bool
5959
filename string
6060
all bool
6161
selector string
6262
allNamespaces bool
63-
resources string
63+
resources []string
6464

6565
cmdFullName string
6666

6767
ClientForMappingFn func(*meta.RESTMapping) (resource.RESTClient, error)
6868
ClientConfig *rest.Config
69-
ClientSet kinternalclientset.Interface
69+
ClientSet clientset.Interface
7070
Mapper meta.RESTMapper
7171

72-
nowTime time.Time
73-
svcBuilder *resource.Builder
72+
// TODO(juanvallejo): remove this once we switch unidling helpers to use external versions
73+
InternalClientset kinternalclientset.Interface
74+
75+
Builder func() *resource.Builder
76+
Namespace string
77+
nowTime time.Time
7478

7579
genericclioptions.IOStreams
7680
}
@@ -110,7 +114,8 @@ func NewCmdIdle(fullName string, f kcmdutil.Factory, streams genericclioptions.I
110114
}
111115

112116
func (o *IdleOptions) Complete(f kcmdutil.Factory, cmd *cobra.Command, args []string) error {
113-
namespace, _, err := f.ToRawKubeConfigLoader().Namespace()
117+
var err error
118+
o.Namespace, _, err = f.ToRawKubeConfigLoader().Namespace()
114119
if err != nil {
115120
return err
116121
}
@@ -127,7 +132,7 @@ func (o *IdleOptions) Complete(f kcmdutil.Factory, cmd *cobra.Command, args []st
127132
return err
128133
}
129134

130-
o.ClientSet, err = f.ClientSet()
135+
o.ClientSet, err = clientset.NewForConfig(o.ClientConfig)
131136
if err != nil {
132137
return err
133138
}
@@ -137,33 +142,15 @@ func (o *IdleOptions) Complete(f kcmdutil.Factory, cmd *cobra.Command, args []st
137142
return err
138143
}
139144

140-
o.ClientForMappingFn = f.ClientForMapping
141-
142-
o.svcBuilder = f.NewBuilder().
143-
WithScheme(ocscheme.ReadingInternalScheme).
144-
ContinueOnError().
145-
NamespaceParam(namespace).DefaultNamespace().AllNamespaces(o.allNamespaces).
146-
Flatten().
147-
SingleResourceType()
148-
149-
if len(o.filename) > 0 {
150-
targetServiceNames, err := scanLinesFromFile(o.filename)
151-
if err != nil {
152-
return err
153-
}
154-
o.svcBuilder.ResourceNames("endpoints", targetServiceNames...)
155-
} else {
156-
// NB: this is a bit weird because the resource builder will complain if we use ResourceTypes and ResourceNames when len(args) > 0
157-
if o.selector != "" {
158-
o.svcBuilder.LabelSelectorParam(o.selector).ResourceTypes("endpoints")
159-
}
145+
o.InternalClientset, err = f.ClientSet()
146+
if err != nil {
147+
return err
148+
}
160149

161-
o.svcBuilder.ResourceNames("endpoints", args...)
150+
o.ClientForMappingFn = f.ClientForMapping
151+
o.Builder = f.NewBuilder
162152

163-
if o.all {
164-
o.svcBuilder.ResourceTypes("endpoints").SelectAllParam(o.all)
165-
}
166-
}
153+
o.resources = args
167154

168155
return nil
169156
}
@@ -206,7 +193,7 @@ func scanLinesFromFile(filename string) ([]string, error) {
206193
// idleUpdateInfo contains the required info to annotate an endpoints object
207194
// with the scalable resources that it should unidle
208195
type idleUpdateInfo struct {
209-
obj *kapi.Endpoints
196+
obj *corev1.Endpoints
210197
scaleRefs map[unidlingapi.CrossGroupObjectReference]struct{}
211198
}
212199

@@ -224,9 +211,9 @@ type controllerRef struct {
224211
// Using the list of services, it figures out the associated scalable objects, and returns a map from the endpoints object for the services to
225212
// the list of scalable resources associated with that endpoints object, as well as a map from CrossGroupObjectReferences to scale to 0 to the
226213
// name of the associated service.
227-
func (o *IdleOptions) calculateIdlableAnnotationsByService() (map[types.NamespacedName]idleUpdateInfo, map[namespacedCrossGroupObjectReference]types.NamespacedName, error) {
228-
podsLoaded := make(map[kapi.ObjectReference]*kapi.Pod)
229-
getPod := func(ref kapi.ObjectReference) (*kapi.Pod, error) {
214+
func (o *IdleOptions) calculateIdlableAnnotationsByService(infoVisitor func(resource.VisitorFunc) error) (map[types.NamespacedName]idleUpdateInfo, map[namespacedCrossGroupObjectReference]types.NamespacedName, error) {
215+
podsLoaded := make(map[corev1.ObjectReference]*corev1.Pod)
216+
getPod := func(ref corev1.ObjectReference) (*corev1.Pod, error) {
230217
if pod, ok := podsLoaded[ref]; ok {
231218
return pod, nil
232219
}
@@ -287,12 +274,12 @@ func (o *IdleOptions) calculateIdlableAnnotationsByService() (map[types.Namespac
287274
targetScaleRefs := make(map[namespacedCrossGroupObjectReference]types.NamespacedName)
288275
endpointsInfo := make(map[types.NamespacedName]idleUpdateInfo)
289276

290-
err := o.svcBuilder.Do().Visit(func(info *resource.Info, err error) error {
277+
err := infoVisitor(func(info *resource.Info, err error) error {
291278
if err != nil {
292279
return err
293280
}
294281

295-
endpoints, isEndpoints := info.Object.(*kapi.Endpoints)
282+
endpoints, isEndpoints := info.Object.(*corev1.Endpoints)
296283
if !isEndpoints {
297284
return fmt.Errorf("you must specify endpoints, not %v (view available endpoints with \"%s get endpoints\").", info.Mapping.Resource, o.cmdFullName)
298285
}
@@ -372,9 +359,9 @@ func normalizedNSOwnerRef(namespace string, ownerRef *metav1.OwnerReference) nam
372359
// scalable objects by checking each address in each subset to see if it has a pod
373360
// reference, and the following that pod reference to find the owning controller,
374361
// and returning the unique set of controllers found this way.
375-
func findScalableResourcesForEndpoints(endpoints *kapi.Endpoints, getPod func(kapi.ObjectReference) (*kapi.Pod, error), getController func(namespacedOwnerReference) (metav1.Object, error)) (map[namespacedCrossGroupObjectReference]struct{}, error) {
362+
func findScalableResourcesForEndpoints(endpoints *corev1.Endpoints, getPod func(corev1.ObjectReference) (*corev1.Pod, error), getController func(namespacedOwnerReference) (metav1.Object, error)) (map[namespacedCrossGroupObjectReference]struct{}, error) {
376363
// To find all RCs and DCs for an endpoint, we first figure out which pods are pointed to by that endpoint...
377-
podRefs := map[kapi.ObjectReference]*kapi.Pod{}
364+
podRefs := map[corev1.ObjectReference]*corev1.Pod{}
378365
for _, subset := range endpoints.Subsets {
379366
for _, addr := range subset.Addresses {
380367
if addr.TargetRef != nil && addr.TargetRef.Kind == "Pod" {
@@ -547,6 +534,32 @@ type scaleInfo struct {
547534
// scalable resources to zero, and annotating the associated endpoints objects with the scalable resources to unidle
548535
// when they receive traffic.
549536
func (o *IdleOptions) RunIdle() error {
537+
b := o.Builder().
538+
WithScheme(ocscheme.ReadingInternalScheme, ocscheme.ReadingInternalScheme.PrioritizedVersionsAllGroups()...).
539+
ContinueOnError().
540+
NamespaceParam(o.Namespace).DefaultNamespace().AllNamespaces(o.allNamespaces).
541+
Flatten().
542+
SingleResourceType()
543+
544+
if len(o.filename) > 0 {
545+
targetServiceNames, err := scanLinesFromFile(o.filename)
546+
if err != nil {
547+
return err
548+
}
549+
b.ResourceNames("endpoints", targetServiceNames...)
550+
} else {
551+
// NB: this is a bit weird because the resource builder will complain if we use ResourceTypes and ResourceNames when len(args) > 0
552+
if o.selector != "" {
553+
b.LabelSelectorParam(o.selector).ResourceTypes("endpoints")
554+
}
555+
556+
b.ResourceNames("endpoints", o.resources...)
557+
558+
if o.all {
559+
b.ResourceTypes("endpoints").SelectAllParam(o.all)
560+
}
561+
}
562+
550563
hadError := false
551564
nowTime := time.Now().UTC()
552565

@@ -556,7 +569,7 @@ func (o *IdleOptions) RunIdle() error {
556569
}
557570

558571
// figure out which endpoints and resources we need to idle
559-
byService, byScalable, err := o.calculateIdlableAnnotationsByService()
572+
byService, byScalable, err := o.calculateIdlableAnnotationsByService(b.Do().Visit)
560573

561574
if err != nil {
562575
if len(byService) == 0 || len(byScalable) == 0 {
@@ -576,7 +589,7 @@ func (o *IdleOptions) RunIdle() error {
576589

577590
externalKubeExtensionClient := kextensionsclient.New(o.ClientSet.Extensions().RESTClient())
578591
delegScaleGetter := appsmanualclient.NewDelegatingScaleNamespacer(appsV1Client, externalKubeExtensionClient)
579-
scaleAnnotater := utilunidling.NewScaleAnnotater(delegScaleGetter, appClient.Apps(), o.ClientSet.Core(), func(currentReplicas int32, annotations map[string]string) {
592+
scaleAnnotater := utilunidling.NewScaleAnnotater(delegScaleGetter, appClient.Apps(), o.InternalClientset.Core(), func(currentReplicas int32, annotations map[string]string) {
580593
annotations[unidlingapi.IdledAtAnnotation] = nowTime.UTC().Format(time.RFC3339)
581594
annotations[unidlingapi.PreviousScaleAnnotation] = fmt.Sprintf("%v", currentReplicas)
582595
})
@@ -679,7 +692,7 @@ func (o *IdleOptions) RunIdle() error {
679692
for scaleRef, info := range toScale {
680693
if !o.dryRun {
681694
info.scale.Spec.Replicas = 0
682-
scaleUpdater := utilunidling.NewScaleUpdater(kcmdutil.InternalVersionJSONEncoder(), info.namespace, appClient.Apps(), o.ClientSet.Core())
695+
scaleUpdater := utilunidling.NewScaleUpdater(kcmdutil.InternalVersionJSONEncoder(), info.namespace, appClient.Apps(), o.InternalClientset.Core())
683696
if err := scaleAnnotater.UpdateObjectScale(scaleUpdater, info.namespace, scaleRef.CrossGroupObjectReference, info.obj, info.scale); err != nil {
684697
fmt.Fprintf(o.ErrOut, "error: unable to scale %s %s/%s to 0, but still listed as target for unidling: %v\n", scaleRef.Kind, info.namespace, scaleRef.Name, err)
685698
hadError = true

Diff for: ‎pkg/unidling/util/scale.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,21 @@ package util
33
import (
44
"github.com/golang/glog"
55

6-
kapiv1 "k8s.io/api/core/v1"
6+
corev1 "k8s.io/api/core/v1"
77
kextapi "k8s.io/api/extensions/v1beta1"
88
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
99
"k8s.io/apimachinery/pkg/runtime"
1010
"k8s.io/apimachinery/pkg/types"
1111
"k8s.io/apimachinery/pkg/util/strategicpatch"
1212
kextensionsclient "k8s.io/client-go/kubernetes/typed/extensions/v1beta1"
1313
kapi "k8s.io/kubernetes/pkg/apis/core"
14-
kcoreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
1514

1615
appsapiv1 "github.com/openshift/api/apps/v1"
1716
"github.com/openshift/origin/pkg/api/legacy"
1817
appsapi "github.com/openshift/origin/pkg/apps/apis/apps"
1918
appsclient "github.com/openshift/origin/pkg/apps/generated/internalclientset/typed/apps/internalversion"
2019
unidlingapi "github.com/openshift/origin/pkg/unidling/api"
20+
kcoreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
2121
)
2222

2323
// TODO: remove the below functions once we get a way to mark/unmark an object as idled
@@ -107,7 +107,7 @@ func (s scaleUpdater) Update(annotator *ScaleAnnotater, obj runtime.Object, scal
107107
return err
108108
}
109109

110-
patchBytes, err = strategicpatch.CreateTwoWayMergePatch(originalObj, newObj, &kapiv1.ReplicationController{})
110+
patchBytes, err = strategicpatch.CreateTwoWayMergePatch(originalObj, newObj, &corev1.ReplicationController{})
111111
if err != nil {
112112
return err
113113
}

0 commit comments

Comments
 (0)
Please sign in to comment.