diff --git a/pkg/functions/client.go b/pkg/functions/client.go index 526a2b579a..5b86078dfe 100644 --- a/pkg/functions/client.go +++ b/pkg/functions/client.go @@ -191,6 +191,7 @@ type Instance struct { Deployer string `json:"deployer" yaml:"deployer"` Subscriptions []Subscription `json:"subscriptions" yaml:"subscriptions"` Labels map[string]string `json:"labels" yaml:"labels" xml:"-"` + Middleware Middleware `json:"middleware,omitempty" yaml:"middleware,omitempty"` } // Subscriptions currently active to event sources @@ -200,6 +201,10 @@ type Subscription struct { Broker string `json:"broker" yaml:"broker"` } +type Middleware struct { + Version string `json:"version" yaml:"version"` +} + // DNSProvider exposes DNS services necessary for serving the function. type DNSProvider interface { // Provide the given name by routing requests to address. diff --git a/pkg/functions/middleware.go b/pkg/functions/middleware.go new file mode 100644 index 0000000000..11d88100ca --- /dev/null +++ b/pkg/functions/middleware.go @@ -0,0 +1,37 @@ +package functions + +import ( + "github.com/google/go-containerregistry/pkg/name" + "github.com/google/go-containerregistry/pkg/v1/remote" +) + +// MiddlewareVersion gets the used middleware version of a function image. +// Returns an empty string and no error in case the function image was built +// without this information. +func MiddlewareVersion(image string) (string, error) { + ref, err := name.ParseReference(image) + if err != nil { + return "", err + } + + desc, err := remote.Get(ref) + if err != nil { + return "", err + } + + img, err := desc.Image() + if err != nil { + return "", err + } + + cfg, err := img.ConfigFile() + if err != nil { + return "", err + } + + if cfg.Config.Labels == nil { + return "", nil + } + + return cfg.Config.Labels[MiddlewareVersionLabelKey], nil +} diff --git a/pkg/k8s/describer.go b/pkg/k8s/describer.go index 3e2c4d87c5..f95d87de4c 100644 --- a/pkg/k8s/describer.go +++ b/pkg/k8s/describer.go @@ -65,6 +65,15 @@ func (d *Describer) Describe(ctx context.Context, name, namespace string) (fn.In } } + middlewareVersion := "" + if image != "" { + v, err := fn.MiddlewareVersion(image) + if err == nil { + // don't fail on errors + middlewareVersion = v + } + } + description := fn.Instance{ Name: name, Namespace: namespace, @@ -73,6 +82,9 @@ func (d *Describer) Describe(ctx context.Context, name, namespace string) (fn.In Route: primaryRouteURL, Routes: []string{primaryRouteURL}, Image: image, + Middleware: fn.Middleware{ + Version: middlewareVersion, + }, } return description, nil diff --git a/pkg/knative/describer.go b/pkg/knative/describer.go index 960a11446d..b40cd68f0f 100644 --- a/pkg/knative/describer.go +++ b/pkg/knative/describer.go @@ -114,6 +114,16 @@ func (d *Describer) Describe(ctx context.Context, name, namespace string) (fn.In } } + if description.Image != "" { + v, err := fn.MiddlewareVersion(description.Image) + if err == nil { + // don't fail on errors + description.Middleware = fn.Middleware{ + Version: v, + } + } + } + triggers, err := eventingClient.ListTriggers(ctx) if err != nil { if errors.IsNotFound(err) || IsCRDNotFoundError(err) {