// New creates a new Clientset for the given RESTClient. func New(c restclient.Interface) *Clientset { var clientset Clientset clientset.CoreClient = internalversioncore.New(c) clientset.DiscoveryClient = discovery.NewDiscoveryClient(c) return &clientset }
// RunIdle runs the idling command logic, taking a list of resources or services in a file, scaling the associated // scalable resources to zero, and annotating the associated endpoints objects with the scalable resources to unidle // when they receive traffic. func (o *IdleOptions) RunIdle(f *clientcmd.Factory) error { hadError := false nowTime := time.Now().UTC() // figure out which endpoints and resources we need to idle byService, byScalable, err := o.calculateIdlableAnnotationsByService(f) if err != nil { if len(byService) == 0 || len(byScalable) == 0 { return fmt.Errorf("no valid scalable resources found to idle: %v", err) } fmt.Fprintf(o.errOut, "warning: continuing on for valid scalable resources, but an error occurred while finding scalable resources to idle: %v", err) } oclient, kclient, err := f.Clients() if err != nil { return err } delegScaleGetter := osclient.NewDelegatingScaleNamespacer(oclient, kclient.Extensions()) dcGetter := deployclient.New(oclient.RESTClient) scaleAnnotater := utilunidling.NewScaleAnnotater(delegScaleGetter, dcGetter, kclient.Core(), func(currentReplicas int32, annotations map[string]string) { annotations[unidlingapi.IdledAtAnnotation] = nowTime.UTC().Format(time.RFC3339) annotations[unidlingapi.PreviousScaleAnnotation] = fmt.Sprintf("%v", currentReplicas) }) replicas := make(map[unidlingapi.CrossGroupObjectReference]int32, len(byScalable)) toScale := make(map[unidlingapi.CrossGroupObjectReference]scaleInfo) mapper, typer := f.Object() // first, collect the scale info for scaleRef, svcName := range byScalable { obj, scale, err := scaleAnnotater.GetObjectWithScale(svcName.Namespace, scaleRef) if err != nil { fmt.Fprintf(o.errOut, "error: unable to get scale for %s %s/%s, not marking that scalable as idled: %v\n", scaleRef.Kind, svcName.Namespace, scaleRef.Name, err) svcInfo := byService[svcName] delete(svcInfo.scaleRefs, scaleRef) hadError = true continue } replicas[scaleRef] = scale.Spec.Replicas toScale[scaleRef] = scaleInfo{scale: scale, obj: obj, namespace: svcName.Namespace} } // annotate the endpoints objects to indicate which scalable resources need to be unidled on traffic for serviceName, info := range byService { if info.obj.Annotations == nil { info.obj.Annotations = make(map[string]string) } refsWithScale, err := pairScalesWithScaleRefs(serviceName, info.obj.Annotations, info.scaleRefs, replicas) if err != nil { fmt.Fprintf(o.errOut, "error: unable to mark service %s as idled: %v", serviceName.String(), err) continue } if !o.dryRun { if len(info.scaleRefs) == 0 { fmt.Fprintf(o.errOut, "error: no scalable resources marked as idled for service %s, not marking as idled\n", serviceName.String()) hadError = true continue } metadata, err := meta.Accessor(info.obj) if err != nil { fmt.Fprintf(o.errOut, "error: unable to mark service %s as idled: %v", serviceName.String(), err) hadError = true continue } gvks, _, err := typer.ObjectKinds(info.obj) if err != nil { fmt.Fprintf(o.errOut, "error: unable to mark service %s as idled: %v", serviceName.String(), err) hadError = true continue } oldData, err := json.Marshal(info.obj) if err != nil { fmt.Fprintf(o.errOut, "error: unable to mark service %s as idled: %v", serviceName.String(), err) hadError = true continue } mapping, err := mapper.RESTMapping(gvks[0].GroupKind(), gvks[0].Version) if err != nil { fmt.Fprintf(o.errOut, "error: unable to mark service %s as idled: %v", serviceName.String(), err) hadError = true continue } if err = setIdleAnnotations(serviceName, info.obj.Annotations, refsWithScale, nowTime); err != nil { fmt.Fprintf(o.errOut, "error: unable to mark service %s as idled: %v", serviceName.String(), err) hadError = true continue } if _, err := patchObj(info.obj, metadata, oldData, mapping, f); err != nil { fmt.Fprintf(o.errOut, "error: unable to mark service %s as idled: %v", serviceName.String(), err) hadError = true continue } } for _, scaleRef := range refsWithScale { fmt.Fprintf(o.out, "Marked service %s to unidle resource %s %s/%s (unidle to %v replicas)\n", serviceName.String(), scaleRef.Kind, serviceName.Namespace, scaleRef.Name, scaleRef.Replicas) } } // actually "idle" the scalable resources by scaling them down to zero // (scale down to zero *after* we've applied the annotation so that we don't miss any traffic) for scaleRef, info := range toScale { idled := "" if !o.dryRun { info.scale.Spec.Replicas = 0 scaleUpdater := utilunidling.NewScaleUpdater(f.JSONEncoder(), info.namespace, dcGetter, kclient.Core()) if err := scaleAnnotater.UpdateObjectScale(scaleUpdater, info.namespace, scaleRef, info.obj, info.scale); err != nil { 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) hadError = true continue } } else { idled = "(dry run)" } fmt.Fprintf(o.out, "Idled %s %s/%s %s\n", scaleRef.Kind, info.namespace, scaleRef.Name, idled) } if hadError { return cmdutil.ErrExit } return nil }