blob: 3b5d41bd847ab45bbfad9cfea1f267186fe2b302 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package discovery
import (
"context"
"fmt"
"github.com/apache/incubator-kie-kogito-serverless-operator/controllers/knative"
"github.com/apache/incubator-kie-kogito-serverless-operator/log"
"k8s.io/client-go/rest"
"k8s.io/klog/v2"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
clienteventingv1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1"
clientservingv1 "knative.dev/serving/pkg/client/clientset/versioned/typed/serving/v1"
)
const (
knServiceKind = "services"
knBrokerKind = "brokers"
)
type knServiceCatalog struct {
dc *KnDiscoveryClient
}
type KnDiscoveryClient struct {
ServingClient clientservingv1.ServingV1Interface
EventingClient clienteventingv1.EventingV1Interface
}
func newKnServiceCatalog(discoveryClient *KnDiscoveryClient) knServiceCatalog {
return knServiceCatalog{
dc: discoveryClient,
}
}
func newKnServiceCatalogForConfig(cfg *rest.Config) knServiceCatalog {
return knServiceCatalog{
dc: newKnDiscoveryClientForConfig(cfg),
}
}
// newKnDiscoveryClientForConfig returns a KnDiscoveryClient discovery client depending on the cluster status, if knative
// serving nor knative eventing are installed, or it was not possible to create that client, returns null.
func newKnDiscoveryClientForConfig(cfg *rest.Config) *KnDiscoveryClient {
var servingClient clientservingv1.ServingV1Interface
var eventingClient clienteventingv1.EventingV1Interface
if avail, err := knative.GetKnativeAvailability(cfg); err != nil {
klog.V(log.E).ErrorS(err, "Unable to determine if knative is installed in the cluster")
return nil
} else {
if avail.Serving {
if servingClient, err = knative.GetKnativeServingClient(cfg); err != nil {
klog.V(log.E).ErrorS(err, "Unable to get the knative serving client")
return nil
}
}
if avail.Eventing {
if eventingClient, err = knative.GetKnativeEventingClient(cfg); err != nil {
klog.V(log.E).ErrorS(err, "Unable to get the knative eventing client")
return nil
}
}
if servingClient != nil || eventingClient != nil {
return newKnDiscoveryClient(servingClient, eventingClient)
}
}
return nil
}
func newKnDiscoveryClient(servingClient clientservingv1.ServingV1Interface, eventingClient clienteventingv1.EventingV1Interface) *KnDiscoveryClient {
return &KnDiscoveryClient{
ServingClient: servingClient,
EventingClient: eventingClient,
}
}
func (c knServiceCatalog) Query(ctx context.Context, uri ResourceUri, outputFormat string) (string, error) {
if c.dc == nil {
return "", fmt.Errorf("knative KnDiscoveryClient was not provided, maybe knative is not installed in current cluster")
}
switch uri.GVK.Kind {
case knServiceKind:
return c.resolveKnServiceQuery(ctx, uri)
case knBrokerKind:
return c.resolveKnBrokerQuery(ctx, uri)
default:
return "", fmt.Errorf("resolution of knative kind: %s is not implemented", uri.GVK.Kind)
}
}
func (c knServiceCatalog) resolveKnServiceQuery(ctx context.Context, uri ResourceUri) (string, error) {
if c.dc.ServingClient == nil {
return "", fmt.Errorf("knative ServingClient was not provided, maybe the serving.knative.dev api is not installed in current cluster")
}
if service, err := c.dc.ServingClient.Services(uri.Namespace).Get(ctx, uri.Name, metav1.GetOptions{}); err != nil {
return "", err
} else {
// knative objects discovery should rely on the addressable interface
return service.Status.Address.URL.String(), nil
}
}
func (c knServiceCatalog) resolveKnBrokerQuery(ctx context.Context, uri ResourceUri) (string, error) {
if c.dc.EventingClient == nil {
return "", fmt.Errorf("knative EventingClient was not provided, maybe the eventing.knative.dev api is not installed in current cluster")
}
if broker, err := c.dc.EventingClient.Brokers(uri.Namespace).Get(ctx, uri.Name, metav1.GetOptions{}); err != nil {
return "", err
} else {
// knative objects discovery should rely on the addressable interface
return broker.Status.Address.URL.String(), nil
}
}