Skip to content

Commit

Permalink
Add annotationFilter to Ambassador Hosts
Browse files Browse the repository at this point in the history
This commit allows users to filter the Host resources based on
a given annotation using `--annotation-filter`.

This commit uses the same `AnnotationFilter` that is
already available (so a new type was not added) and already used
by many other source types.

Signed-off-by: Ricardo Nales Amato <ricardo.amato@tradeshift.com>
  • Loading branch information
Ricardo Nales Amato committed Apr 9, 2021
1 parent 43d29f8 commit 3b26557
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 4 deletions.
53 changes: 50 additions & 3 deletions source/ambassador_host.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ type ambassadorHostSource struct {
dynamicKubeClient dynamic.Interface
kubeClient kubernetes.Interface
namespace string
annotationFilter string
ambassadorHostInformer informers.GenericInformer
unstructuredConverter *unstructuredConverter
}
Expand All @@ -68,7 +69,8 @@ type ambassadorHostSource struct {
func NewAmbassadorHostSource(
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 @@ -104,6 +106,7 @@ func NewAmbassadorHostSource(
dynamicKubeClient: dynamicKubeClient,
kubeClient: kubeClient,
namespace: namespace,
annotationFilter: annotationFilter,
ambassadorHostInformer: ambassadorHostInformer,
unstructuredConverter: uc,
}, nil
Expand All @@ -112,13 +115,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 @@ -130,6 +136,16 @@ 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 @@ -281,3 +297,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 HTTPProxy's annotations to an equivalent label selector
annotations := labels.Set(host.Annotations)

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

return filteredList, nil
}
2 changes: 1 addition & 1 deletion source/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ func BuildWithConfig(source string, p ClientGenerator, cfg *Config) (Source, err
if err != nil {
return nil, err
}
return NewAmbassadorHostSource(dynamicClient, kubernetesClient, cfg.Namespace)
return NewAmbassadorHostSource(dynamicClient, kubernetesClient, cfg.Namespace, cfg.AnnotationFilter)
case "contour-ingressroute":
kubernetesClient, err := p.KubeClient()
if err != nil {
Expand Down

0 comments on commit 3b26557

Please sign in to comment.