Skip to content

Commit 3940adf

Browse files
Merge pull request #20343 from juanvallejo/jvallejo/switch-more-cmds-to-externals
switch logs, idle commands to externals
2 parents 0c4c2ad + 62c5374 commit 3940adf

File tree

9 files changed

+273
-145
lines changed

9 files changed

+273
-145
lines changed

hack/import-restrictions.json

+2
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,8 @@
450450

451451
"github.com/openshift/origin/pkg/apps/generated",
452452
"github.com/openshift/origin/pkg/authorization/generated",
453+
"github.com/openshift/origin/pkg/build/apis/build/v1",
454+
"github.com/openshift/origin/pkg/build/client/v1",
453455
"github.com/openshift/origin/pkg/build/generated",
454456
"github.com/openshift/origin/pkg/image/generated",
455457
"github.com/openshift/origin/pkg/network/generated",

pkg/build/client/v1/logs.go

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package v1
2+
3+
import (
4+
"k8s.io/client-go/rest"
5+
"k8s.io/kubernetes/pkg/api/legacyscheme"
6+
7+
buildv1 "github.com/openshift/api/build/v1"
8+
)
9+
10+
type BuildLogInterface interface {
11+
Logs(name string, options buildv1.BuildLogOptions) *rest.Request
12+
}
13+
14+
func NewBuildLogClient(c rest.Interface, ns string) BuildLogInterface {
15+
return &buildLogs{client: c, ns: ns}
16+
}
17+
18+
type buildLogs struct {
19+
client rest.Interface
20+
ns string
21+
}
22+
23+
func (c *buildLogs) Logs(name string, options buildv1.BuildLogOptions) *rest.Request {
24+
return c.client.
25+
Get().
26+
Namespace(c.ns).
27+
Resource("builds").
28+
Name(name).
29+
SubResource("log").
30+
VersionedParams(&options, legacyscheme.ParameterCodec)
31+
}

pkg/oc/cli/idle/idle.go

+60-46
Original file line numberDiff line numberDiff line change
@@ -11,29 +11,31 @@ 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"
2929
"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource"
30+
"k8s.io/kubernetes/pkg/kubectl/scheme"
3031

3132
appsv1client "github.com/openshift/client-go/apps/clientset/versioned/typed/apps/v1"
3233
appsmanualclient "github.com/openshift/origin/pkg/apps/client/v1"
3334
appsclientinternal "github.com/openshift/origin/pkg/apps/generated/internalclientset"
3435
"github.com/openshift/origin/pkg/oc/util/ocscheme"
3536
unidlingapi "github.com/openshift/origin/pkg/unidling/api"
3637
utilunidling "github.com/openshift/origin/pkg/unidling/util"
38+
kinternalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
3739
)
3840

3941
var (
@@ -54,23 +56,26 @@ var (
5456
)
5557

5658
type IdleOptions struct {
57-
dryRun bool
58-
59+
dryRun bool
5960
filename string
6061
all bool
6162
selector string
6263
allNamespaces bool
63-
resources string
64+
resources []string
6465

6566
cmdFullName string
6667

6768
ClientForMappingFn func(*meta.RESTMapping) (resource.RESTClient, error)
6869
ClientConfig *rest.Config
69-
ClientSet kinternalclientset.Interface
70+
ClientSet clientset.Interface
7071
Mapper meta.RESTMapper
7172

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

7580
genericclioptions.IOStreams
7681
}
@@ -110,7 +115,8 @@ func NewCmdIdle(fullName string, f kcmdutil.Factory, streams genericclioptions.I
110115
}
111116

112117
func (o *IdleOptions) Complete(f kcmdutil.Factory, cmd *cobra.Command, args []string) error {
113-
namespace, _, err := f.ToRawKubeConfigLoader().Namespace()
118+
var err error
119+
o.Namespace, _, err = f.ToRawKubeConfigLoader().Namespace()
114120
if err != nil {
115121
return err
116122
}
@@ -127,7 +133,7 @@ func (o *IdleOptions) Complete(f kcmdutil.Factory, cmd *cobra.Command, args []st
127133
return err
128134
}
129135

130-
o.ClientSet, err = f.ClientSet()
136+
o.ClientSet, err = clientset.NewForConfig(o.ClientConfig)
131137
if err != nil {
132138
return err
133139
}
@@ -137,33 +143,15 @@ func (o *IdleOptions) Complete(f kcmdutil.Factory, cmd *cobra.Command, args []st
137143
return err
138144
}
139145

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-
}
146+
o.InternalClientset, err = f.ClientSet()
147+
if err != nil {
148+
return err
149+
}
160150

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

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

168156
return nil
169157
}
@@ -206,7 +194,7 @@ func scanLinesFromFile(filename string) ([]string, error) {
206194
// idleUpdateInfo contains the required info to annotate an endpoints object
207195
// with the scalable resources that it should unidle
208196
type idleUpdateInfo struct {
209-
obj *kapi.Endpoints
197+
obj *corev1.Endpoints
210198
scaleRefs map[unidlingapi.CrossGroupObjectReference]struct{}
211199
}
212200

@@ -224,9 +212,9 @@ type controllerRef struct {
224212
// Using the list of services, it figures out the associated scalable objects, and returns a map from the endpoints object for the services to
225213
// the list of scalable resources associated with that endpoints object, as well as a map from CrossGroupObjectReferences to scale to 0 to the
226214
// 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) {
215+
func (o *IdleOptions) calculateIdlableAnnotationsByService(infoVisitor func(resource.VisitorFunc) error) (map[types.NamespacedName]idleUpdateInfo, map[namespacedCrossGroupObjectReference]types.NamespacedName, error) {
216+
podsLoaded := make(map[corev1.ObjectReference]*corev1.Pod)
217+
getPod := func(ref corev1.ObjectReference) (*corev1.Pod, error) {
230218
if pod, ok := podsLoaded[ref]; ok {
231219
return pod, nil
232220
}
@@ -287,12 +275,12 @@ func (o *IdleOptions) calculateIdlableAnnotationsByService() (map[types.Namespac
287275
targetScaleRefs := make(map[namespacedCrossGroupObjectReference]types.NamespacedName)
288276
endpointsInfo := make(map[types.NamespacedName]idleUpdateInfo)
289277

290-
err := o.svcBuilder.Do().Visit(func(info *resource.Info, err error) error {
278+
err := infoVisitor(func(info *resource.Info, err error) error {
291279
if err != nil {
292280
return err
293281
}
294282

295-
endpoints, isEndpoints := info.Object.(*kapi.Endpoints)
283+
endpoints, isEndpoints := info.Object.(*corev1.Endpoints)
296284
if !isEndpoints {
297285
return fmt.Errorf("you must specify endpoints, not %v (view available endpoints with \"%s get endpoints\").", info.Mapping.Resource, o.cmdFullName)
298286
}
@@ -372,9 +360,9 @@ func normalizedNSOwnerRef(namespace string, ownerRef *metav1.OwnerReference) nam
372360
// scalable objects by checking each address in each subset to see if it has a pod
373361
// reference, and the following that pod reference to find the owning controller,
374362
// 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) {
363+
func findScalableResourcesForEndpoints(endpoints *corev1.Endpoints, getPod func(corev1.ObjectReference) (*corev1.Pod, error), getController func(namespacedOwnerReference) (metav1.Object, error)) (map[namespacedCrossGroupObjectReference]struct{}, error) {
376364
// 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{}
365+
podRefs := map[corev1.ObjectReference]*corev1.Pod{}
378366
for _, subset := range endpoints.Subsets {
379367
for _, addr := range subset.Addresses {
380368
if addr.TargetRef != nil && addr.TargetRef.Kind == "Pod" {
@@ -547,6 +535,32 @@ type scaleInfo struct {
547535
// scalable resources to zero, and annotating the associated endpoints objects with the scalable resources to unidle
548536
// when they receive traffic.
549537
func (o *IdleOptions) RunIdle() error {
538+
b := o.Builder().
539+
WithScheme(scheme.Scheme, scheme.Scheme.PrioritizedVersionsAllGroups()...).
540+
ContinueOnError().
541+
NamespaceParam(o.Namespace).DefaultNamespace().AllNamespaces(o.allNamespaces).
542+
Flatten().
543+
SingleResourceType()
544+
545+
if len(o.filename) > 0 {
546+
targetServiceNames, err := scanLinesFromFile(o.filename)
547+
if err != nil {
548+
return err
549+
}
550+
b.ResourceNames("endpoints", targetServiceNames...)
551+
} else {
552+
// NB: this is a bit weird because the resource builder will complain if we use ResourceTypes and ResourceNames when len(args) > 0
553+
if o.selector != "" {
554+
b.LabelSelectorParam(o.selector).ResourceTypes("endpoints")
555+
}
556+
557+
b.ResourceNames("endpoints", o.resources...)
558+
559+
if o.all {
560+
b.ResourceTypes("endpoints").SelectAllParam(o.all)
561+
}
562+
}
563+
550564
hadError := false
551565
nowTime := time.Now().UTC()
552566

@@ -556,7 +570,7 @@ func (o *IdleOptions) RunIdle() error {
556570
}
557571

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

561575
if err != nil {
562576
if len(byService) == 0 || len(byScalable) == 0 {
@@ -576,7 +590,7 @@ func (o *IdleOptions) RunIdle() error {
576590

577591
externalKubeExtensionClient := kextensionsclient.New(o.ClientSet.Extensions().RESTClient())
578592
delegScaleGetter := appsmanualclient.NewDelegatingScaleNamespacer(appsV1Client, externalKubeExtensionClient)
579-
scaleAnnotater := utilunidling.NewScaleAnnotater(delegScaleGetter, appClient.Apps(), o.ClientSet.Core(), func(currentReplicas int32, annotations map[string]string) {
593+
scaleAnnotater := utilunidling.NewScaleAnnotater(delegScaleGetter, appClient.Apps(), o.InternalClientset.Core(), func(currentReplicas int32, annotations map[string]string) {
580594
annotations[unidlingapi.IdledAtAnnotation] = nowTime.UTC().Format(time.RFC3339)
581595
annotations[unidlingapi.PreviousScaleAnnotation] = fmt.Sprintf("%v", currentReplicas)
582596
})
@@ -679,7 +693,7 @@ func (o *IdleOptions) RunIdle() error {
679693
for scaleRef, info := range toScale {
680694
if !o.dryRun {
681695
info.scale.Spec.Replicas = 0
682-
scaleUpdater := utilunidling.NewScaleUpdater(kcmdutil.InternalVersionJSONEncoder(), info.namespace, appClient.Apps(), o.ClientSet.Core())
696+
scaleUpdater := utilunidling.NewScaleUpdater(kcmdutil.InternalVersionJSONEncoder(), info.namespace, appClient.Apps(), o.InternalClientset.Core())
683697
if err := scaleAnnotater.UpdateObjectScale(scaleUpdater, info.namespace, scaleRef.CrossGroupObjectReference, info.obj, info.scale); err != nil {
684698
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)
685699
hadError = true

pkg/oc/cli/idle/idle_test.go

+16-15
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,23 @@ import (
55
"fmt"
66
"testing"
77

8-
unidlingapi "github.com/openshift/origin/pkg/unidling/api"
9-
10-
oappsapi "github.com/openshift/origin/pkg/apps/apis/apps"
8+
corev1 "k8s.io/api/core/v1"
119
kerrors "k8s.io/apimachinery/pkg/api/errors"
1210
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1311
"k8s.io/apimachinery/pkg/runtime/schema"
1412
ktypes "k8s.io/apimachinery/pkg/types"
1513
kapi "k8s.io/kubernetes/pkg/apis/core"
1614

15+
oappsapi "github.com/openshift/origin/pkg/apps/apis/apps"
16+
unidlingapi "github.com/openshift/origin/pkg/unidling/api"
17+
1718
// install all APIs
1819
_ "github.com/openshift/origin/pkg/api/install"
1920
_ "k8s.io/kubernetes/pkg/apis/core/install"
2021
)
2122

22-
func makePod(name string, rc metav1.Object, namespace string, t *testing.T) kapi.Pod {
23-
pod := kapi.Pod{
23+
func makePod(name string, rc metav1.Object, namespace string, t *testing.T) corev1.Pod {
24+
pod := corev1.Pod{
2425
ObjectMeta: metav1.ObjectMeta{
2526
Name: name,
2627
Namespace: namespace,
@@ -49,8 +50,8 @@ func makeRC(name string, dc metav1.Object, namespace string, t *testing.T) *kapi
4950
return &rc
5051
}
5152

52-
func makePodRef(name, namespace string) *kapi.ObjectReference {
53-
return &kapi.ObjectReference{
53+
func makePodRef(name, namespace string) *corev1.ObjectReference {
54+
return &corev1.ObjectReference{
5455
Kind: "Pod",
5556
Name: name,
5657
Namespace: namespace,
@@ -63,18 +64,18 @@ func makeRCRef(name string) *metav1.OwnerReference {
6364
}
6465

6566
func TestFindIdlablesForEndpoints(t *testing.T) {
66-
endpoints := &kapi.Endpoints{
67-
Subsets: []kapi.EndpointSubset{
67+
endpoints := &corev1.Endpoints{
68+
Subsets: []corev1.EndpointSubset{
6869
{
69-
Addresses: []kapi.EndpointAddress{
70+
Addresses: []corev1.EndpointAddress{
7071
{
7172
TargetRef: makePodRef("somepod1", "somens1"),
7273
},
7374
{
7475
TargetRef: makePodRef("somepod2", "somens1"),
7576
},
7677
{
77-
TargetRef: &kapi.ObjectReference{
78+
TargetRef: &corev1.ObjectReference{
7879
Kind: "Cheese",
7980
Name: "cheddar",
8081
Namespace: "somens",
@@ -83,7 +84,7 @@ func TestFindIdlablesForEndpoints(t *testing.T) {
8384
},
8485
},
8586
{
86-
Addresses: []kapi.EndpointAddress{
87+
Addresses: []corev1.EndpointAddress{
8788
{},
8889
{
8990
TargetRef: makePodRef("somepod3", "somens1"),
@@ -100,7 +101,7 @@ func TestFindIdlablesForEndpoints(t *testing.T) {
100101
},
101102
},
102103
{
103-
Addresses: []kapi.EndpointAddress{
104+
Addresses: []corev1.EndpointAddress{
104105
{},
105106
{
106107
TargetRef: makePodRef("somepod1", "somens2"),
@@ -119,7 +120,7 @@ func TestFindIdlablesForEndpoints(t *testing.T) {
119120
"somens2/somerc2": makeRC("somerc2", nil, "somens2", t),
120121
}
121122

122-
pods := map[kapi.ObjectReference]kapi.Pod{
123+
pods := map[corev1.ObjectReference]corev1.Pod{
123124
*makePodRef("somepod1", "somens1"): makePod("somepod1", controllers["somens1/somerc1"], "somens1", t),
124125
*makePodRef("somepod2", "somens1"): makePod("somepod2", controllers["somens1/somerc2"], "somens1", t),
125126
*makePodRef("somepod3", "somens1"): makePod("somepod3", controllers["somens1/somerc1"], "somens1", t),
@@ -128,7 +129,7 @@ func TestFindIdlablesForEndpoints(t *testing.T) {
128129
*makePodRef("somepod1", "somens2"): makePod("somepod5", controllers["somens2/somerc2"], "somens2", t),
129130
}
130131

131-
getPod := func(ref kapi.ObjectReference) (*kapi.Pod, error) {
132+
getPod := func(ref corev1.ObjectReference) (*corev1.Pod, error) {
132133
if pod, ok := pods[ref]; ok {
133134
return &pod, nil
134135
}

0 commit comments

Comments
 (0)