Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions cmd/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,9 @@ func (items listItems) Plain(w io.Writer) error {
tabWriter := tabwriter.NewWriter(w, 0, 8, 2, ' ', 0)
defer tabWriter.Flush()

fmt.Fprintf(tabWriter, "%s\t%s\t%s\t%s\t%s\t%s\n", "NAME", "NAMESPACE", "RUNTIME", "DEPLOYER", "URL", "READY")
fmt.Fprintf(tabWriter, "%s\t%s\t%s\t%s\t%s\t%s\t%s\n", "NAME", "NAMESPACE", "RUNTIME", "DEPLOYER", "URL", "READY", "REPLICAS")
for _, item := range items {
fmt.Fprintf(tabWriter, "%s\t%s\t%s\t%s\t%s\t%s\n", item.Name, item.Namespace, item.Runtime, item.Deployer, item.URL, item.Ready)
fmt.Fprintf(tabWriter, "%s\t%s\t%s\t%s\t%s\t%s\t%d\n", item.Name, item.Namespace, item.Runtime, item.Deployer, item.URL, item.Ready, item.Replicas)
}
return nil
}
Expand Down
1 change: 1 addition & 0 deletions pkg/functions/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ type ListItem struct {
URL string `json:"url" yaml:"url"`
Ready string `json:"ready" yaml:"ready"`
Deployer string `json:"deployer" yaml:"deployer"`
Replicas int `json:"replicas" yaml:"replicas"`
}

// Describer of function instances
Expand Down
1 change: 1 addition & 0 deletions pkg/k8s/lister.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ func (l *Lister) get(ctx context.Context, clientset *kubernetes.Clientset, name,
URL: fmt.Sprintf("http://%s.%s.svc", service.Name, service.Namespace), // TODO: use correct scheme
Ready: string(ready),
Deployer: KubernetesDeployerName,
Replicas: int(deployment.Status.ReadyReplicas),
}

return listItem, nil
Expand Down
12 changes: 10 additions & 2 deletions pkg/keda/lister.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
fn "knative.dev/func/pkg/functions"
"knative.dev/func/pkg/k8s"
"knative.dev/func/pkg/k8s/labels"
Expand Down Expand Up @@ -61,7 +62,7 @@ func (l *Lister) List(ctx context.Context, namespace string) ([]fn.ListItem, err
}

runtime := service.Labels[labels.FunctionRuntimeKey]
item, err := l.get(ctx, httpScaledObjectClientset, service.Name, service.Namespace, runtime)
item, err := l.get(ctx, clientset, httpScaledObjectClientset, service.Name, service.Namespace, runtime)
if err != nil {
return nil, fmt.Errorf("unable to get details about function: %v", err)
}
Expand All @@ -73,12 +74,18 @@ func (l *Lister) List(ctx context.Context, namespace string) ([]fn.ListItem, err
}

// Get a function, optionally specifying a namespace.
func (l *Lister) get(ctx context.Context, httpScaledObjectClientset *versioned.Clientset, name, namespace, runtime string) (fn.ListItem, error) {
func (l *Lister) get(ctx context.Context, clientset *kubernetes.Clientset, httpScaledObjectClientset *versioned.Clientset, name, namespace, runtime string) (fn.ListItem, error) {
httpScaledObject, err := httpScaledObjectClientset.HttpV1alpha1().HTTPScaledObjects(namespace).Get(ctx, name, metav1.GetOptions{})
if err != nil {
return fn.ListItem{}, fmt.Errorf("unable to get HTTPScaledObject: %v", err)
}

deployment, err := clientset.AppsV1().Deployments(namespace).Get(ctx, name, metav1.GetOptions{})
if err != nil {
return fn.ListItem{}, fmt.Errorf("unable to get deployment: %v", err)
}
replicas := int(deployment.Status.ReadyReplicas)

ready := v1.ConditionUnknown
if meta.IsStatusConditionTrue(httpScaledObject.Status.Conditions, v1alpha1.ConditionTypeReady) {
ready = v1.ConditionTrue
Expand All @@ -98,6 +105,7 @@ func (l *Lister) get(ctx context.Context, httpScaledObjectClientset *versioned.C
URL: url,
Ready: string(ready),
Deployer: KedaDeployerName,
Replicas: replicas,
}

return listItem, nil
Expand Down
28 changes: 26 additions & 2 deletions pkg/knative/lister.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
clientservingv1 "knative.dev/client/pkg/serving/v1"
"knative.dev/func/pkg/k8s"
"knative.dev/func/pkg/k8s/labels"
Expand All @@ -33,12 +34,12 @@ func (l *Lister) List(ctx context.Context, namespace string) ([]fn.ListItem, err

restConfig, err := l.kc.ClientConfig()
if err != nil {
return nil, fmt.Errorf("failed to get kubernetes client config: %v", err)
return nil, fmt.Errorf("unable to get kubernetes client config: %w", err)
}

servingClient, err := servingv1.NewForConfig(restConfig)
if err != nil {
return nil, fmt.Errorf("failed to create serving client: %v", err)
return nil, fmt.Errorf("unable to create serving client: %w", err)
}

client := clientservingv1.NewKnServingClient(servingClient, namespace)
Expand Down Expand Up @@ -80,6 +81,11 @@ func (l *Lister) List(ctx context.Context, namespace string) ([]fn.ListItem, err
}
}

replicas, err := readyReplicas(ctx, servingClient, service.Namespace, service.Status.LatestReadyRevisionName)
if err != nil {
return nil, fmt.Errorf("unable to get replicas for %s: %w", service.Name, err)
}

runtimeLabel := service.Labels[labels.FunctionRuntimeKey]

listItem := fn.ListItem{
Expand All @@ -89,10 +95,28 @@ func (l *Lister) List(ctx context.Context, namespace string) ([]fn.ListItem, err
URL: service.Status.URL.String(),
Ready: string(ready),
Deployer: KnativeDeployerName,
Replicas: replicas,
}

items = append(items, listItem)
}

return items, nil
}

func readyReplicas(ctx context.Context, client servingv1.ServingV1Interface, namespace, revision string) (int, error) {
if revision == "" {
return 0, nil
}
rev, err := client.Revisions(namespace).Get(ctx, revision, metav1.GetOptions{})
if err != nil {
if errors.IsNotFound(err) {
return 0, nil
}
return 0, err
}
if rev.Status.ActualReplicas == nil {
return 0, nil
}
return int(*rev.Status.ActualReplicas), nil
}
15 changes: 9 additions & 6 deletions pkg/lister/testing/integration_test_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,15 +87,18 @@ func TestInt_List(t *testing.T, lister fn.Lister, deployer fn.Deployer, describe
}

// Should find at least our function (may have others in namespace)
found := false
for _, item := range list {
if item.Name == f.Name {
found = true
var found *fn.ListItem
for i := range list {
if list[i].Name == f.Name {
found = &list[i]
break
}
}
if !found {
t.Errorf("function %s not found in list", f.Name)
if found == nil {
t.Fatalf("function %s not found in list", f.Name)
}

if found.Replicas < 1 {
t.Errorf("expected function %s to report >= 1 replica, got %d", f.Name, found.Replicas)
}
}
Loading