/
describer.go
107 lines (89 loc) · 3.23 KB
/
describer.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package knative
import (
"fmt"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/rest"
"knative.dev/eventing/pkg/apis/eventing/v1alpha1"
eventingv1client "knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1alpha1"
servingv1client "knative.dev/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1"
"github.com/boson-project/faas"
"github.com/boson-project/faas/k8s"
)
type Describer struct {
Verbose bool
namespace string
servingClient *servingv1client.ServingV1alpha1Client
eventingClient *eventingv1client.EventingV1alpha1Client
config *rest.Config
}
func NewDescriber(namespaceOverride string) (describer *Describer, err error) {
describer = &Describer{}
config, namespace, err := newClientConfig(namespaceOverride)
if err != nil {
return
}
describer.namespace = namespace
describer.servingClient, err = servingv1client.NewForConfig(config)
if err != nil {
return
}
describer.eventingClient, err = eventingv1client.NewForConfig(config)
if err != nil {
return
}
describer.config = config
return
}
// Describe by name. Note that the consuming API uses domain style notation, whereas Kubernetes
// restricts to label-syntax, which is thus escaped. Therefore as a knative (kube) implementation
// detal proper full names have to be escaped on the way in and unescaped on the way out. ex:
// www.example-site.com -> www-example--site-com
func (describer *Describer) Describe(name string) (description faas.Description, err error) {
namespace := describer.namespace
servingClient := describer.servingClient
eventingClient := describer.eventingClient
serviceName, err := k8s.ToSubdomain(name)
if err != nil {
return
}
service, err := servingClient.Services(namespace).Get(serviceName, metav1.GetOptions{})
if err != nil {
return
}
serviceLabel := fmt.Sprintf("serving.knative.dev/service=%s", serviceName)
routes, err := servingClient.Routes(namespace).List(metav1.ListOptions{LabelSelector: serviceLabel})
if err != nil {
return
}
routeURLs := make([]string, 0, len(routes.Items))
for _, route := range routes.Items {
routeURLs = append(routeURLs, route.Status.URL.String())
}
triggers, err := eventingClient.Triggers(namespace).List(metav1.ListOptions{})
// IsNotFound -- Eventing is probably not installed on the cluster
if err != nil && !errors.IsNotFound(err) {
return
}
triggerMatches := func(t *v1alpha1.Trigger) bool {
return (t.Spec.Subscriber.Ref != nil && t.Spec.Subscriber.Ref.Name == service.Name) ||
(t.Spec.Subscriber.URI != nil && service.Status.Address != nil && service.Status.Address.URL != nil &&
t.Spec.Subscriber.URI.Path == service.Status.Address.URL.Path)
}
subscriptions := make([]faas.Subscription, 0, len(triggers.Items))
for _, trigger := range triggers.Items {
if triggerMatches(&trigger) {
filterAttrs := *trigger.Spec.Filter.Attributes
subscription := faas.Subscription{
Source: filterAttrs["source"],
Type: filterAttrs["type"],
Broker: trigger.Spec.Broker,
}
subscriptions = append(subscriptions, subscription)
}
}
description.Routes = routeURLs
description.Subscriptions = subscriptions
description.Name, err = k8s.FromSubdomain(service.Name)
return
}