Repository: zalando-incubator/kube-ingress-aws-controller
Pull request #528 (2022-07-25 13:43:14)

Remove FabricGateway support
Initial support #474 was implemented as a part of an effort to make
FabricGateway a Skipper-native route format.

Since then the approach has changed and there is a plan to use a new controller
that would translate FabricGateway into equivalent RouteGroup.

Since RouteGroups are natively supported by Skipper and Ingress
Controller there is no need to keep track of the FabricGateway
loadbalancer name in the status.

Signed-off-by: Alexander Yastrebov <alexander.yastrebov@zalando.de>


Patch:
diff --git a/README.md b/README.md
index 3609eb2..bc8b8ca 100644
--- a/README.md
+++ b/README.md
@@ -33,7 +33,6 @@ This information is used to manage AWS resources for each ingress objects of the
 - Support for AWS WAF and WAFv2
 - Support for AWS CNI pod direct access
 - Support for Kubernetes CRD [RouteGroup](https://opensource.zalando.com/skipper/kubernetes/routegroups/)
-- Support for Kubernetes CRD [FabricGateway](https://opensource.zalando.com/skipper/kubernetes/fabricgateways/)
 
 ## Upgrade
 
diff --git a/deploy/ingress-serviceaccount.yaml b/deploy/ingress-serviceaccount.yaml
index f631536..0509b75 100644
--- a/deploy/ingress-serviceaccount.yaml
+++ b/deploy/ingress-serviceaccount.yaml
@@ -39,7 +39,6 @@ rules:
   - zalando.org
   resources:
   - routegroups
-  - fabricgateways
   verbs:
   - get
   - list
@@ -47,7 +46,6 @@ rules:
   - zalando.org
   resources:
   - routegroups/status
-  - fabricgateways/status
   verbs:
   - patch
   - update
diff --git a/deploy/skipper-serviceaccount.yaml b/deploy/skipper-serviceaccount.yaml
index b8f7d37..ac5ff7e 100644
--- a/deploy/skipper-serviceaccount.yaml
+++ b/deploy/skipper-serviceaccount.yaml
@@ -22,7 +22,6 @@ rules:
   - zalando.org
   resources:
   - routegroups
-  - fabricgateways
   verbs:
   - get
   - list
diff --git a/kubernetes/adapter.go b/kubernetes/adapter.go
index beb1225..9263982 100644
--- a/kubernetes/adapter.go
+++ b/kubernetes/adapter.go
@@ -23,15 +23,13 @@ type Adapter struct {
 	ingressDefaultLoadBalancerType string
 	clusterLocalDomain             string
 	routeGroupSupport              bool
-	fabricSupport                  bool
 }
 
 type IngressType string
 
 const (
-	TypeIngress       IngressType = "ingress"
-	TypeRouteGroup    IngressType = "routegroup"
-	TypeFabricGateway IngressType = "fabricgateway"
+	TypeIngress    IngressType = "ingress"
+	TypeRouteGroup IngressType = "routegroup"
 )
 
 const (
@@ -126,7 +124,6 @@ func NewAdapter(config *Config, ingressAPIVersion string, ingressClassFilters []
 		ingressDefaultLoadBalancerType: loadBalancerTypesAWSToIngress[ingressDefaultLoadBalancerType],
 		clusterLocalDomain:             clusterLocalDomain,
 		routeGroupSupport:              true,
-		fabricSupport:                  true,
 	}, nil
 }
 
@@ -168,34 +165,6 @@ func (a *Adapter) newIngressFromRouteGroup(rg *routegroup) (*Ingress, error) {
 	return a.newIngress(TypeRouteGroup, rg.Metadata, host, hostnames)
 }
 
-func (a *Adapter) newIngressFromFabric(fg *fabric) (*Ingress, error) {
-	var host string
-	var hostnames []string
-	for _, lb := range fg.Status.LoadBalancer.Fabric {
-		if lb.Hostname != "" {
-			host = lb.Hostname
-			break
-		}
-	}
-
-	switch {
-	case len(fg.Spec.Service) > 0:
-		for _, svc := range fg.Spec.Service {
-			if svc.Host != "" && (a.clusterLocalDomain == "" || !strings.HasSuffix(svc.Host, a.clusterLocalDomain)) {
-				hostnames = append(hostnames, svc.Host)
-			}
-		}
-	case fg.Spec.ExternalServiceProvider != nil:
-		for _, host := range fg.Spec.ExternalServiceProvider.Hosts {
-			if host != "" && (a.clusterLocalDomain == "" || !strings.HasSuffix(host, a.clusterLocalDomain)) {
-				hostnames = append(hostnames, host)
-			}
-		}
-	}
-
-	return a.newIngress(TypeFabricGateway, fg.Metadata, host, hostnames)
-}
-
 func (a *Adapter) newIngress(typ IngressType, metadata kubeItemMetadata, host string, hostnames []string) (*Ingress, error) {
 	annotations := metadata.Annotations
 
@@ -290,10 +259,10 @@ func (a *Adapter) IngressFiltersString() string {
 	return strings.TrimSpace(strings.Join(a.ingressFilters, ","))
 }
 
-// ListResources can be used to obtain the list of ingress, routegroup and
-// fabric resources for all namespaces filtered by class. It
+// ListResources can be used to obtain the list of ingress and routegroup
+// resources for all namespaces filtered by class. It
 // returns the Ingress business object, that for the controller does
-// not matter to be fabricgateway, routegroup or ingress..
+// not matter to be routegroup or ingress..
 func (a *Adapter) ListResources() ([]*Ingress, error) {
 	ings, err := a.ListIngress()
 	if err != nil {
@@ -314,28 +283,14 @@ func (a *Adapter) ListResources() ([]*Ingress, error) {
 		}
 	}
 
-	var fgs []*Ingress
-	if a.fabricSupport {
-		fgs, err = a.ListFabricgateways()
-		if err != nil {
-			if errors.Is(err, ErrResourceNotFound) || errors.Is(err, ErrNoPermissionToAccessResource) {
-				a.fabricSupport = false
-				log.Warnf("Disabling FabricGateway support because listing FabricGateways failed: %v, to get more information https://opensource.zalando.com/skipper/kubernetes/fabric/#fabricgateways", err)
-			} else {
-				// Generic error, FabricGateway CRD exists and we have permission to access
-				return nil, err
-			}
-		}
-	}
-
 	ings = append(ings, rgs...)
-	return append(ings, fgs...), nil
+	return ings, nil
 }
 
 // ListIngress can be used to obtain the list of ingress resources for
 // all namespaces filtered by class. It returns the Ingress business
 // object, that for the controller does not matter to be
-// fabricgateway, routegroup or ingress..
+// routegroup or ingress..
 func (a *Adapter) ListIngress() ([]*Ingress, error) {
 	il, err := a.ingressClient.listIngress(a.kubeClient)
 	if err != nil {
@@ -363,7 +318,7 @@ func (a *Adapter) ListIngress() ([]*Ingress, error) {
 // ListRoutegroups can be used to obtain the list of Ingress resources
 // for all namespaces filtered by class. It returns the Ingress
 // business object, that for the controller does not matter to be
-// fabricgateway, routegroup or ingress.
+// routegroup or ingress.
 func (a *Adapter) ListRoutegroups() ([]*Ingress, error) {
 	rgs, err := listRoutegroups(a.kubeClient)
 	if err != nil {
@@ -389,35 +344,6 @@ func (a *Adapter) ListRoutegroups() ([]*Ingress, error) {
 	return ret, nil
 }
 
-// ListFabricgateways can be used to obtain the list of Ingress resources
-// for all namespaces filtered by class. It returns the Ingress
-// business object, that for the controller does not matter to be
-// fabricgateway, routegroup or ingress.
-func (a *Adapter) ListFabricgateways() ([]*Ingress, error) {
-	fgs, err := listFabricgateways(a.kubeClient)
-	if err != nil {
-		return nil, err
-	}
-
-	var ret []*Ingress
-	for _, fg := range fgs.Items {
-		if !a.supportedCRD(fg.Metadata) {
-			continue
-		}
-		ing, err := a.newIngressFromFabric(fg)
-		if err == nil {
-			ret = append(ret, ing)
-		} else {
-			log.WithFields(log.Fields{
-				"type": TypeFabricGateway,
-				"ns":   fg.Metadata.Namespace,
-				"name": fg.Metadata.Name,
-			}).Errorf("%v", err)
-		}
-	}
-	return ret, nil
-}
-
 func (a *Adapter) supportedCRD(metadata kubeItemMetadata) bool {
 	if len(a.ingressFilters) == 0 {
 		return true
@@ -464,8 +390,6 @@ func (a *Adapter) UpdateIngressLoadBalancer(ingress *Ingress, loadBalancerDNSNam
 	}
 
 	switch ingress.ResourceType {
-	case TypeFabricGateway:
-		return updateFabricgatewayLoadBalancer(a.kubeClient, ingress.Namespace, ingress.Name, loadBalancerDNSName)
 	case TypeRouteGroup:
 		return updateRoutegroupLoadBalancer(a.kubeClient, ingress.Namespace, ingress.Name, loadBalancerDNSName)
 	case TypeIngress:
diff --git a/kubernetes/fabric.go b/kubernetes/fabric.go
deleted file mode 100644
index 5def97f..0000000
--- a/kubernetes/fabric.go
+++ /dev/null
@@ -1,103 +0,0 @@
-package kubernetes
-
-import (
-	"encoding/json"
-	"fmt"
-	"io"
-)
-
-const (
-	fabricListResource        = "/apis/zalando.org/v1/fabricgateways"
-	fabricNamespacedResource  = "/apis/zalando.org/v1/namespaces/%s/fabricgateways/%s"
-	fabricPatchStatusResource = "/apis/zalando.org/v1/namespaces/%s/fabricgateways/%s/status"
-)
-
-type fabricList struct {
-	Kind       string             `json:"kind"`
-	APIVersion string             `json:"apiVersion"`
-	Metadata   fabricListMetadata `json:"metadata"`
-	Items      []*fabric          `json:"items"`
-}
-
-type fabric struct {
-	Metadata kubeItemMetadata `json:"metadata"`
-	Spec     fabricSpec       `json:"spec"`
-	Status   fabricStatus     `json:"status"`
-}
-
-type fabricListMetadata struct {
-	SelfLink        string `json:"selfLink"`
-	ResourceVersion string `json:"resourceVersion"`
-}
-
-type fabricSpec struct {
-	Service                 []*fabricService               `json:"x-fabric-service"`
-	ExternalServiceProvider *fabricExternalServiceProvider `json:"x-external-service-provider"`
-}
-
-type fabricService struct {
-	Host string `json:"host"`
-}
-type fabricExternalServiceProvider struct {
-	Hosts []string `json:"hosts"`
-}
-
-type fabricStatus struct {
-	LoadBalancer fabricLoadBalancerStatus `json:"loadBalancer"`
-}
-
-type fabricLoadBalancerStatus struct {
-	Fabric []fabricLoadBalancer `json:"fabricgateway"`
-}
-
-type fabricLoadBalancer struct {
-	Hostname string `json:"hostname"`
-}
-
-func listFabricgateways(c client) (*fabricList, error) {
-	r, err := c.get(fabricListResource)
-	if err != nil {
-		return nil, err
-	}
-
-	defer r.Close()
-
-	b, err := io.ReadAll(r)
-	if err != nil {
-		return nil, err
-	}
-
-	var result fabricList
-	if err := json.Unmarshal(b, &result); err != nil {
-		return nil, err
-	}
-
-	return &result, nil
-}
-
-type patchFabricStatus struct {
-	Status fabricStatus `json:"status"`
-}
-
-func updateFabricgatewayLoadBalancer(c client, ns, name, newHostName string) error {
-	patchStatus := patchFabricStatus{
-		Status: fabricStatus{
-			LoadBalancer: fabricLoadBalancerStatus{
-				Fabric: []fabricLoadBalancer{{Hostname: newHostName}},
-			},
-		},
-	}
-
-	resource := fmt.Sprintf(fabricPatchStatusResource, ns, name)
-	payload, err := json.Marshal(patchStatus)
-	if err != nil {
-		return err
-	}
-
-	r, err := c.patch(resource, payload)
-	if err != nil {
-		return fmt.Errorf("failed to patch fabric %s/%s = %q: %w", ns, name, newHostName, err)
-	}
-	defer r.Close()
-	return nil
-}
diff --git a/metrics.go b/metrics.go
index b2d6621..83f0d76 100644
--- a/metrics.go
+++ b/metrics.go
@@ -12,7 +12,6 @@ var metrics = struct {
 	lastSyncTimestamp              prometheus.Gauge
 	ingressesTotal                 prometheus.Gauge
 	routegroupsTotal               prometheus.Gauge
-	fabricgatewaysTotal            prometheus.Gauge
 	stacksTotal                    prometheus.Gauge
 	ownedAutoscalingGroupsTotal    prometheus.Gauge
 	targetedAutoscalingGroupsTotal prometheus.Gauge
@@ -46,14 +45,6 @@ var metrics = struct {
 			Help:      "Number of managed Route Groups",
 		},
 	),
-	fabricgatewaysTotal: prometheus.NewGauge(
-		prometheus.GaugeOpts{
-			Namespace: "kube_ingress_aws",
-			Subsystem: "controller",
-			Name:      "fabricgateways_total",
-			Help:      "Number of managed Fabric Gateways",
-		},
-	),
 	stacksTotal: prometheus.NewGauge(
 		prometheus.GaugeOpts{
 			Namespace: "kube_ingress_aws",
@@ -115,7 +106,7 @@ var metrics = struct {
 			Namespace: "kube_ingress_aws",
 			Subsystem: "controller",
 			Name:      "changes_total",
-			Help:      "Number of Cloud Formation stack, Kubernetes Ingress, Route Group and Fabric Gateway changes",
+			Help:      "Number of Cloud Formation stack, Kubernetes Ingress and Route Group changes",
 		},
 		[]string{"resource_type", "operation"},
 	)},
@@ -141,7 +132,6 @@ func registerMetrics() {
 	prometheus.MustRegister(metrics.lastSyncTimestamp)
 	prometheus.MustRegister(metrics.ingressesTotal)
 	prometheus.MustRegister(metrics.routegroupsTotal)
-	prometheus.MustRegister(metrics.fabricgatewaysTotal)
 	prometheus.MustRegister(metrics.stacksTotal)
 	prometheus.MustRegister(metrics.ownedAutoscalingGroupsTotal)
 	prometheus.MustRegister(metrics.targetedAutoscalingGroupsTotal)
diff --git a/worker.go b/worker.go
index 95743c6..f7fceed 100644
--- a/worker.go
+++ b/worker.go
@@ -307,7 +307,6 @@ func doWork(
 
 	metrics.ingressesTotal.Set(float64(counts[kubernetes.TypeIngress]))
 	metrics.routegroupsTotal.Set(float64(counts[kubernetes.TypeRouteGroup]))
-	metrics.fabricgatewaysTotal.Set(float64(counts[kubernetes.TypeFabricGateway]))
 	metrics.stacksTotal.Set(float64(len(stacks)))
 	metrics.ownedAutoscalingGroupsTotal.Set(float64(len(awsAdapter.OwnedAutoScalingGroups)))
 	metrics.targetedAutoscalingGroupsTotal.Set(float64(len(awsAdapter.TargetedAutoScalingGroups)))
@@ -318,7 +317,6 @@ func doWork(
 
 	log.Debugf("Found %d ingress(es)", counts[kubernetes.TypeIngress])
 	log.Debugf("Found %d route group(s)", counts[kubernetes.TypeRouteGroup])
-	log.Debugf("Found %d fabric gateway(s)", counts[kubernetes.TypeFabricGateway])
 	log.Debugf("Found %d stack(s)", len(stacks))
 	log.Debugf("Found %d owned auto scaling group(s)", len(awsAdapter.OwnedAutoScalingGroups))
 	log.Debugf("Found %d targeted auto scaling group(s)", len(awsAdapter.TargetedAutoScalingGroups))


Test patch:
diff --git a/kubernetes/adapter_test.go b/kubernetes/adapter_test.go
index 9d9794d..ecbb123 100644
--- a/kubernetes/adapter_test.go
+++ b/kubernetes/adapter_test.go
@@ -488,8 +488,6 @@ func (c *mockClient) get(res string) (io.ReadCloser, error) {
 
 	var fixture string
 	switch res {
-	case fabricListResource:
-		fixture = "testdata/fixture01_fg.json"
 	case routegroupListResource:
 		fixture = "testdata/fixture01_rg.json"
 	case fmt.Sprintf(ingressListResource, IngressAPIVersionNetworking):
@@ -514,8 +512,6 @@ func (c *mockClient) patch(res string, payload []byte) (io.ReadCloser, error) {
 			return io.NopCloser(strings.NewReader(":)")), nil
 		case "/apis/zalando.org/v1/namespaces/default/routegroups/foo/status":
 			return io.NopCloser(strings.NewReader(":)")), nil
-		case "/apis/zalando.org/v1/namespaces/default/fabricgateways/foo/status":
-			return io.NopCloser(strings.NewReader(":)")), nil
 		}
 	}
 	return nil, errors.New("mocked error")
@@ -597,35 +593,6 @@ func TestUpdateRouteGroupLoadBalancer(t *testing.T) {
 	}
 }
 
-func TestUpdateFabricGatewayLoadBalancer(t *testing.T) {
-	a, _ := NewAdapter(testConfig, IngressAPIVersionNetworking, testIngressFilter, testSecurityGroup, testSSLPolicy, aws.LoadBalancerTypeApplication, DefaultClusterLocalDomain, false)
-	client := &mockClient{}
-	a.kubeClient = client
-	ing := &Ingress{
-		Namespace:      "default",
-		Name:           "foo",
-		Hostname:       "bar",
-		CertificateARN: "zbr",
-		ResourceType:   TypeFabricGateway,
-	}
-	if err := a.UpdateIngressLoadBalancer(ing, "bar"); err != ErrUpdateNotNeeded {
-		t.Error("expected ErrUpdateNotNeeded")
-	}
-	if err := a.UpdateIngressLoadBalancer(ing, "xpto"); err != nil {
-		t.Error(err)
-	}
-	client.broken = true
-	if err := a.UpdateIngressLoadBalancer(ing, "xpto"); err == nil {
-		t.Error("expected an error")
-	}
-	if err := a.UpdateIngressLoadBalancer(ing, ""); err == nil {
-		t.Error("expected an error")
-	}
-	if err := a.UpdateIngressLoadBalancer(nil, "xpto"); err == nil {
-		t.Error("expected an error")
-	}
-}
-
 func TestBrokenConfig(t *testing.T) {
 	for _, test := range []struct {
 		name string
@@ -684,9 +651,6 @@ func TestListIngressFilterClass(t *testing.T) {
 				"fixture-rg01",
 				"fixture-rg02",
 				"fixture-rg03",
-				"fixture-fg01",
-				"fixture-fg02",
-				"fixture-fg03",
 			},
 		},
 		"emptyIngressClassFilters2": {
@@ -700,9 +664,6 @@ func TestListIngressFilterClass(t *testing.T) {
 				"fixture-rg01",
 				"fixture-rg02",
 				"fixture-rg03",
-				"fixture-fg01",
-				"fixture-fg02",
-				"fixture-fg03",
 			},
 		},
 		"singleIngressClass1": {
@@ -710,7 +671,6 @@ func TestListIngressFilterClass(t *testing.T) {
 			expectedIngressNames: []string{
 				"fixture02",
 				"fixture-rg02",
-				"fixture-fg02",
 			},
 		},
 		"singleIngressClass2": {
@@ -718,7 +678,6 @@ func TestListIngressFilterClass(t *testing.T) {
 			expectedIngressNames: []string{
 				"fixture03",
 				"fixture-rg03",
-				"fixture-fg03",
 			},
 		},
 		"multipleIngressClass": {
@@ -728,8 +687,6 @@ func TestListIngressFilterClass(t *testing.T) {
 				"fixture03",
 				"fixture-rg02",
 				"fixture-rg03",
-				"fixture-fg02",
-				"fixture-fg03",
 			},
 		},
 		"multipleIngressClassWithDefault": {
@@ -739,8 +696,6 @@ func TestListIngressFilterClass(t *testing.T) {
 				"fixture02",
 				"fixture-rg01",
 				"fixture-rg02",
-				"fixture-fg01",
-				"fixture-fg02",
 			},
 		},
 		"multipleIngressClassWithDefault2": {
@@ -750,8 +705,6 @@ func TestListIngressFilterClass(t *testing.T) {
 				"fixture03",
 				"fixture-rg01",
 				"fixture-rg03",
-				"fixture-fg01",
-				"fixture-fg03",
 			},
 		},
 		"multipleIngressClassMixedAnnotationAndSpec": {
@@ -759,7 +712,6 @@ func TestListIngressFilterClass(t *testing.T) {
 			expectedIngressNames: []string{
 				"fixture03",
 				"fixture-rg03",
-				"fixture-fg03",
 				"fixture04",
 			},
 		},
diff --git a/kubernetes/fabric_test.go b/kubernetes/fabric_test.go
deleted file mode 100644
index ef6ee5d..0000000
--- a/kubernetes/fabric_test.go
+++ /dev/null
@@ -1,180 +0,0 @@
-package kubernetes
-
-import (
-	"fmt"
-	"io"
-	"net/http"
-	"net/http/httptest"
-	"os"
-	"testing"
-	"time"
-
-	"github.com/google/go-cmp/cmp"
-)
-
-func TestListFabricgateways(t *testing.T) {
-	testServer := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
-		f, _ := os.Open("testdata/fixture01_fg.json")
-		defer f.Close()
-		rw.WriteHeader(http.StatusOK)
-		io.Copy(rw, f)
-	}))
-	defer testServer.Close()
-	kubeClient, _ := newSimpleClient(&Config{BaseURL: testServer.URL}, false)
-	want := newFabricgatewayList(
-		newFabricgateway("fixture-fg01", nil, "example.org", "fixture-fg01"),
-		newFabricgateway("fixture-fg02", map[string]string{ingressClassAnnotation: "skipper"}, "skipper.example.org", "fixture-fg02"),
-		newFabricgateway("fixture-fg03", map[string]string{ingressClassAnnotation: "other"}, "other.example.org", "fixture-fg03"),
-	)
-	got, err := listFabricgateways(kubeClient)
-	if err != nil {
-		t.Errorf("unexpected error from listFabricgateways: %v", err)
-	} else {
-		if !cmp.Equal(got, want) {
-			t.Errorf("unexpected result from listFabricgateways. %v", cmp.Diff(want, got))
-		}
-	}
-}
-
-func TestListFabricgatewayFailureScenarios(t *testing.T) {
-	for _, test := range []struct {
-		statusCode int
-		body       string
-	}{
-		{http.StatusInternalServerError, "{}"},
-		{http.StatusOK, "`"},
-	} {
-		t.Run(fmt.Sprintf("%v", test.statusCode), func(t *testing.T) {
-			testServer := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
-				rw.WriteHeader(test.statusCode)
-				fmt.Fprintln(rw, test.body)
-			}))
-			defer testServer.Close()
-			cfg := &Config{BaseURL: testServer.URL}
-			kubeClient, _ := newSimpleClient(cfg, false)
-
-			_, err := listFabricgateways(kubeClient)
-			if err == nil {
-				t.Error("expected an error but list fabric call succeeded")
-			}
-		})
-	}
-}
-
-func TestUpdateFabricgatewayLoadBalancer(t *testing.T) {
-	expectedContentType := map[string]bool{
-		"application/json-patch+json":            true,
-		"application/merge-patch+json":           true,
-		"application/strategic-merge-patch+json": true,
-	}
-	testServer := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
-		if req.URL.Path != fmt.Sprintf(fabricPatchStatusResource, "foo", "bar") {
-			t.Error("unexpected URL path sent by the client", req.URL.Path)
-		}
-		if req.Method != "PATCH" {
-			t.Error("unexpected HTTP method. Wanted PATCH but got", req.Method)
-		}
-		ct := req.Header.Get("Content-Type")
-		if !expectedContentType[ct] {
-			t.Error("unexpected content type", ct)
-		}
-		b, err := io.ReadAll(req.Body)
-		if err != nil {
-			t.Error(err)
-		}
-		got := string(b)
-		expected := `{"status":{"loadBalancer":{"fabricgateway":[{"hostname":"example.org"}]}}}`
-		if got != expected {
-			t.Errorf("unexpected request body. Wanted %s but got %s", expected, got)
-		}
-		rw.WriteHeader(http.StatusOK)
-	}))
-	defer testServer.Close()
-	cfg := &Config{BaseURL: testServer.URL}
-	kubeClient, _ := newSimpleClient(cfg, false)
-
-	if err := updateFabricgatewayLoadBalancer(kubeClient, "foo", "bar", "example.org"); err != nil {
-		t.Error("unexpected result from update call:", err)
-	}
-}
-
-func TestUpdateFabricgatewayFailureScenarios(t *testing.T) {
-	testServer := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
-		rw.WriteHeader(http.StatusInternalServerError)
-	}))
-	defer testServer.Close()
-	cfg := &Config{BaseURL: testServer.URL}
-	kubeClient, _ := newSimpleClient(cfg, false)
-	for _, test := range []struct {
-		fg *fabric
-	}{
-		{newFabricgateway("foo", nil, "example.org", "")},
-	} {
-		arn := getAnnotationsString(test.fg.Metadata.Annotations, ingressCertificateARNAnnotation, "<missing>")
-		t.Run(fmt.Sprintf("%v/%v", test.fg.Status.LoadBalancer.Fabric[0].Hostname, arn), func(t *testing.T) {
-			err := updateRoutegroupLoadBalancer(kubeClient, test.fg.Metadata.Namespace, test.fg.Metadata.Name, "example.com")
-			if err == nil {
-				t.Error("expected an error but update routegroup call succeeded")
-			}
-		})
-	}
-}
-
-func TestFabricgatewayAnnotationsFallback(t *testing.T) {
-	have := &fabric{Metadata: kubeItemMetadata{Annotations: map[string]string{"foo": "bar"}}}
-	for _, test := range []struct {
-		key      string
-		fallback string
-		want     string
-	}{
-		{"foo", "zbr", "bar"},
-		{"missing", "fallback", "fallback"},
-	} {
-		t.Run(fmt.Sprintf("%s/%s/%s", test.key, test.want, test.fallback), func(t *testing.T) {
-			if got := getAnnotationsString(have.Metadata.Annotations, test.key, test.fallback); got != test.want {
-				t.Errorf("unexpected metadata value. wanted %q, got %q", test.want, got)
-			}
-		})
-	}
-}
-
-func newFabricgatewayList(fgs ...*fabric) *fabricList {
-	ret := fabricList{
-		APIVersion: "zalando.org/v1",
-		Kind:       "FabricgatewayList",
-		Metadata: fabricListMetadata{
-			SelfLink:        fabricListResource,
-			ResourceVersion: "42",
-		},
-		Items: fgs,
-	}
-	return &ret
-}
-
-func newFabricgateway(name string, annotations map[string]string, hostname string, arn string) *fabric {
-	ret := fabric{
-		Metadata: kubeItemMetadata{
-			Name:              name,
-			Namespace:         "default",
-			Annotations:       annotations,
-			ResourceVersion:   "42",
-			SelfLink:          fmt.Sprintf(fabricNamespacedResource, "default", name),
-			Generation:        1,
-			UID:               name,
-			CreationTimestamp: time.Date(2016, 11, 29, 14, 53, 42, 0, time.UTC),
-		},
-	}
-	if arn != "" {
-		if annotations == nil {
-			ret.Metadata.Annotations = map[string]string{ingressCertificateARNAnnotation: arn}
-		} else {
-			ret.Metadata.Annotations[ingressCertificateARNAnnotation] = arn
-		}
-	}
-	if hostname != "" {
-		ret.Status.LoadBalancer = fabricLoadBalancerStatus{
-			Fabric: []fabricLoadBalancer{{Hostname: hostname}},
-		}
-	}
-	return &ret
-}
diff --git a/kubernetes/testdata/fixture01_fg.json b/kubernetes/testdata/fixture01_fg.json
deleted file mode 100644
index abd00b7..0000000
--- a/kubernetes/testdata/fixture01_fg.json
+++ /dev/null
@@ -1,75 +0,0 @@
-{
-  "kind": "FabricgatewayList",
-  "apiVersion": "zalando.org/v1",
-  "metadata": {
-    "selfLink": "/apis/zalando.org/v1/fabricgateways",
-    "resourceVersion": "42"
-  },
-  "items": [
-    {
-      "metadata": {
-        "name": "fixture-fg01",
-        "namespace": "default",
-        "selfLink": "/apis/zalando.org/v1/namespaces/default/fabricgateways/fixture-fg01",
-        "uid": "fixture-fg01",
-        "resourceVersion": "42",
-        "generation": 1,
-        "creationTimestamp": "2016-11-29T14:53:42Z",
-        "annotations": {
-          "zalando.org/aws-load-balancer-ssl-cert": "fixture-fg01"
-        }
-      },
-      "status": {
-        "loadBalancer": {
-          "fabricgateway": [
-            {"hostname": "example.org"}
-          ]
-        }
-      }
-    },
-    {
-      "metadata": {
-        "name": "fixture-fg02",
-        "namespace": "default",
-        "selfLink": "/apis/zalando.org/v1/namespaces/default/fabricgateways/fixture-fg02",
-        "uid": "fixture-fg02",
-        "resourceVersion": "42",
-        "generation": 1,
-        "creationTimestamp": "2016-11-29T14:53:42Z",
-        "annotations": {
-          "zalando.org/aws-load-balancer-ssl-cert": "fixture-fg02",
-          "kubernetes.io/ingress.class": "skipper"
-        }
-      },
-      "status": {
-        "loadBalancer": {
-          "fabricgateway": [
-            {"hostname": "skipper.example.org"}
-          ]
-        }
-      }
-    },
-    {
-      "metadata": {
-        "name": "fixture-fg03",
-        "namespace": "default",
-        "selfLink": "/apis/zalando.org/v1/namespaces/default/fabricgateways/fixture-fg03",
-        "uid": "fixture-fg03",
-        "resourceVersion": "42",
-        "generation": 1,
-        "creationTimestamp": "2016-11-29T14:53:42Z",
-        "annotations": {
-          "zalando.org/aws-load-balancer-ssl-cert": "fixture-fg03",
-          "kubernetes.io/ingress.class": "other"
-        }
-      },
-      "status": {
-        "loadBalancer": {
-          "fabricgateway": [
-            {"hostname": "other.example.org"}
-          ]
-        }
-      }
-    }
-  ]
-}
diff --git a/worker_test.go b/worker_test.go
index d1b461c..87abccb 100644
--- a/worker_test.go
+++ b/worker_test.go
@@ -1046,12 +1046,10 @@ func TestCountByIngressType(t *testing.T) {
 		&kubernetes.Ingress{ResourceType: kubernetes.TypeIngress},
 		&kubernetes.Ingress{ResourceType: kubernetes.TypeRouteGroup},
 		&kubernetes.Ingress{ResourceType: kubernetes.TypeRouteGroup},
-		&kubernetes.Ingress{ResourceType: kubernetes.TypeFabricGateway},
 	}
 
 	counts := countByIngressType(ingresses)
 
 	assert.Equal(t, 3, counts[kubernetes.TypeIngress])
 	assert.Equal(t, 2, counts[kubernetes.TypeRouteGroup])
-	assert.Equal(t, 1, counts[kubernetes.TypeFabricGateway])
 }