sigs.k8s.io/kueue@v0.6.2/pkg/visibility/api/rest/pending_workloads_lq.go (about)

     1  // Copyright 2023 The Kubernetes Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package rest
    16  
    17  import (
    18  	"context"
    19  	"fmt"
    20  
    21  	"github.com/go-logr/logr"
    22  	"k8s.io/apimachinery/pkg/api/errors"
    23  	"k8s.io/apimachinery/pkg/runtime"
    24  	genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
    25  	"k8s.io/apiserver/pkg/registry/rest"
    26  	ctrl "sigs.k8s.io/controller-runtime"
    27  
    28  	v1alpha1 "sigs.k8s.io/kueue/apis/visibility/v1alpha1"
    29  	"sigs.k8s.io/kueue/pkg/constants"
    30  	"sigs.k8s.io/kueue/pkg/queue"
    31  
    32  	_ "k8s.io/metrics/pkg/apis/metrics/install"
    33  )
    34  
    35  type pendingWorkloadsInLqREST struct {
    36  	queueMgr *queue.Manager
    37  	log      logr.Logger
    38  }
    39  
    40  var _ rest.Storage = &pendingWorkloadsInLqREST{}
    41  var _ rest.GetterWithOptions = &pendingWorkloadsInLqREST{}
    42  var _ rest.Scoper = &pendingWorkloadsInLqREST{}
    43  
    44  func NewPendingWorkloadsInLqREST(kueueMgr *queue.Manager) *pendingWorkloadsInLqREST {
    45  	return &pendingWorkloadsInLqREST{
    46  		queueMgr: kueueMgr,
    47  		log:      ctrl.Log.WithName("pending-workload-in-lq"),
    48  	}
    49  }
    50  
    51  // New implements rest.Storage interface
    52  func (m *pendingWorkloadsInLqREST) New() runtime.Object {
    53  	return &v1alpha1.PendingWorkloadsSummary{}
    54  }
    55  
    56  // Destroy implements rest.Storage interface
    57  func (m *pendingWorkloadsInLqREST) Destroy() {}
    58  
    59  // Get implements rest.GetterWithOptions interface
    60  // It fetches information about pending workloads and returns according to query params
    61  func (m *pendingWorkloadsInLqREST) Get(ctx context.Context, name string, opts runtime.Object) (runtime.Object, error) {
    62  	pendingWorkloadOpts, ok := opts.(*v1alpha1.PendingWorkloadOptions)
    63  	if !ok {
    64  		return nil, fmt.Errorf("invalid options object: %#v", opts)
    65  	}
    66  	limit := pendingWorkloadOpts.Limit
    67  	offset := pendingWorkloadOpts.Offset
    68  
    69  	namespace := genericapirequest.NamespaceValue(ctx)
    70  	cqName, err := m.queueMgr.ClusterQueueFromLocalQueue(fmt.Sprintf("%s/%s", namespace, name))
    71  	if err != nil {
    72  		return nil, errors.NewNotFound(v1alpha1.Resource("localqueue"), name)
    73  	}
    74  
    75  	wls := make([]v1alpha1.PendingWorkload, 0, limit)
    76  	skippedWls := 0
    77  	for index, wlInfo := range m.queueMgr.PendingWorkloadsInfo(cqName) {
    78  		if len(wls) >= int(limit) {
    79  			break
    80  		}
    81  		if wlInfo.Obj.Spec.QueueName == name {
    82  			if skippedWls < int(offset) {
    83  				skippedWls++
    84  			} else {
    85  				// Add a workload to results
    86  				wls = append(wls, *newPendingWorkload(wlInfo, int32(len(wls)+int(offset)), index))
    87  			}
    88  		}
    89  	}
    90  
    91  	return &v1alpha1.PendingWorkloadsSummary{Items: wls}, nil
    92  }
    93  
    94  // NewGetOptions creates a new options object
    95  func (m *pendingWorkloadsInLqREST) NewGetOptions() (runtime.Object, bool, string) {
    96  	// If no query parameters were passed the generated defaults function are not executed so it's necessary to set default values here as well
    97  	return &v1alpha1.PendingWorkloadOptions{
    98  		Limit: constants.DefaultPendingWorkloadsLimit,
    99  	}, false, ""
   100  }
   101  
   102  // NamespaceScoped implements rest.Scoper interface
   103  func (m *pendingWorkloadsInLqREST) NamespaceScoped() bool {
   104  	return true
   105  }