Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add annotationFilter to Ambassador Hosts #2043

Closed
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
52 changes: 49 additions & 3 deletions source/ambassador_host.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ type ambassadorHostSource struct {
dynamicKubeClient dynamic.Interface
kubeClient kubernetes.Interface
namespace string
annotationFilter string
ambassadorHostInformer informers.GenericInformer
unstructuredConverter *unstructuredConverter
}
Expand All @@ -66,7 +67,8 @@ func NewAmbassadorHostSource(
ctx context.Context,
dynamicKubeClient dynamic.Interface,
kubeClient kubernetes.Interface,
namespace string) (Source, error) {
namespace string,
annotationFilter string) (Source, error) {
var err error

// Use shared informer to listen for add/update/delete of Host in the specified namespace.
Expand Down Expand Up @@ -97,6 +99,7 @@ func NewAmbassadorHostSource(
dynamicKubeClient: dynamicKubeClient,
kubeClient: kubeClient,
namespace: namespace,
annotationFilter: annotationFilter,
ambassadorHostInformer: ambassadorHostInformer,
unstructuredConverter: uc,
}, nil
Expand All @@ -105,13 +108,16 @@ func NewAmbassadorHostSource(
// Endpoints returns endpoint objects for each host-target combination that should be processed.
// Retrieves all Hosts in the source's namespace(s).
func (sc *ambassadorHostSource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, error) {
hosts, err := sc.ambassadorHostInformer.Lister().ByNamespace(sc.namespace).List(labels.Everything())
h, err := sc.ambassadorHostInformer.Lister().ByNamespace(sc.namespace).List(labels.Everything())
if err != nil {
return nil, err
}

// Convert to []*ambassador.Host
var hosts []*ambassador.Host

endpoints := []*endpoint.Endpoint{}
for _, hostObj := range hosts {
for _, hostObj := range h {
unstructuredHost, ok := hostObj.(*unstructured.Unstructured)
if !ok {
return nil, errors.New("could not convert")
Expand All @@ -123,6 +129,15 @@ func (sc *ambassadorHostSource) Endpoints(ctx context.Context) ([]*endpoint.Endp
return nil, err
}

hosts = append(hosts, host)
}

hosts, err = sc.filterByAnnotations(hosts)
if err != nil {
return nil, errors.Wrap(err, "failed to filter Hosts")
}

for _, host := range hosts {
fullname := fmt.Sprintf("%s/%s", host.Namespace, host.Name)

// look for the "exernal-dns.ambassador-service" annotation. If it is not there then just ignore this `Host`
Expand Down Expand Up @@ -274,3 +289,34 @@ func newUnstructuredConverter() (*unstructuredConverter, error) {

return uc, nil
}

// filterByAnnotations filters a list of configs by a given annotation selector.
func (sc *ambassadorHostSource) filterByAnnotations(hosts []*ambassador.Host) ([]*ambassador.Host, error) {
labelSelector, err := metav1.ParseToLabelSelector(sc.annotationFilter)
if err != nil {
return nil, err
}
selector, err := metav1.LabelSelectorAsSelector(labelSelector)
if err != nil {
return nil, err
}

// empty filter returns original list
if selector.Empty() {
return hosts, nil
}

filteredList := []*ambassador.Host{}

for _, host := range hosts {
// convert the Host's annotations to an equivalent label selector
annotations := labels.Set(host.Annotations)

// include Host if its annotations match the selector
if selector.Matches(annotations) {
filteredList = append(filteredList, host)
}
}

return filteredList, nil
}
4 changes: 2 additions & 2 deletions source/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ package source

import (
"context"
"github.com/cloudfoundry-community/go-cfclient"
"net/http"
"os"
"strings"
"sync"
"time"

"github.com/cloudfoundry-community/go-cfclient"
"github.com/linki/instrumented_http"
openshift "github.com/openshift/client-go/route/clientset/versioned"
"github.com/pkg/errors"
Expand Down Expand Up @@ -234,7 +234,7 @@ func BuildWithConfig(ctx context.Context, source string, p ClientGenerator, cfg
if err != nil {
return nil, err
}
return NewAmbassadorHostSource(ctx, dynamicClient, kubernetesClient, cfg.Namespace)
return NewAmbassadorHostSource(ctx, dynamicClient, kubernetesClient, cfg.Namespace, cfg.AnnotationFilter)
case "contour-httpproxy":
dynamicClient, err := p.DynamicKubernetesClient()
if err != nil {
Expand Down