Skip to content

Commit b615bc4

Browse files
committed
status: Add Gateway API objects to relatedObjects
This commit resolves NE-1277. https://issues.redhat.com/browse/NE-1277 * pkg/operator/controller/status/controller.go (New): Add a watch for subscriptions so that the status controller updates relatedObjects with the OSSM subscription when it is added or removed. (Config): Add GatewayAPIEnabled field. (Reconcile): Add dnsrecords in the operand namespace to relatedObjects. If GatewayAPIEnabled is true, add resources related to Gateway API. If haveOSSMSubscription is true, add resources that require the subscription. (operatorState): Add haveOSSMSubscription field. (getOperatorState): Set haveOSSMSubscription. * pkg/operator/operator.go (New): Specify GatewayAPIEnabled in the status controller's config. * test/e2e/operator_test.go (TestClusterOperatorStatusRelatedObjects): Expect to observe "dnsrecords" for the "openshift-ingress" namespace as well as "gatewayclasses" in relatedObjects.
1 parent 1b72b75 commit b615bc4

File tree

3 files changed

+101
-3
lines changed

3 files changed

+101
-3
lines changed

pkg/operator/controller/status/controller.go

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import (
88

99
"github.com/google/go-cmp/cmp"
1010
"github.com/google/go-cmp/cmp/cmpopts"
11+
sailv1 "github.com/istio-ecosystem/sail-operator/api/v1"
12+
operatorsv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1"
1113

1214
configv1 "github.com/openshift/api/config/v1"
1315
operatorv1 "github.com/openshift/api/operator/v1"
@@ -26,9 +28,12 @@ import (
2628
"k8s.io/apimachinery/pkg/types"
2729
utilclock "k8s.io/utils/clock"
2830

31+
gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1"
32+
2933
"sigs.k8s.io/controller-runtime/pkg/cache"
3034
"sigs.k8s.io/controller-runtime/pkg/client"
3135
"sigs.k8s.io/controller-runtime/pkg/controller"
36+
"sigs.k8s.io/controller-runtime/pkg/event"
3237
"sigs.k8s.io/controller-runtime/pkg/handler"
3338
"sigs.k8s.io/controller-runtime/pkg/manager"
3439
"sigs.k8s.io/controller-runtime/pkg/predicate"
@@ -92,11 +97,33 @@ func New(mgr manager.Manager, config Config) (controller.Controller, error) {
9297
if err := c.Watch(source.Kind[client.Object](operatorCache, &configv1.ClusterOperator{}, handler.EnqueueRequestsFromMapFunc(toDefaultIngressController), predicate.NewPredicateFuncs(isIngressClusterOperator))); err != nil {
9398
return nil, err
9499
}
100+
101+
if config.GatewayAPIEnabled {
102+
if err := c.Watch(source.Kind[client.Object](operatorCache, &operatorsv1alpha1.Subscription{}, handler.EnqueueRequestsFromMapFunc(toDefaultIngressController), predicate.Funcs{
103+
CreateFunc: func(e event.CreateEvent) bool {
104+
return e.Object.GetNamespace() == operatorcontroller.OpenshiftOperatorNamespace
105+
},
106+
UpdateFunc: func(e event.UpdateEvent) bool {
107+
return false
108+
},
109+
DeleteFunc: func(e event.DeleteEvent) bool {
110+
return e.Object.GetNamespace() == operatorcontroller.OpenshiftOperatorNamespace
111+
},
112+
GenericFunc: func(e event.GenericEvent) bool {
113+
return false
114+
},
115+
})); err != nil {
116+
return nil, err
117+
}
118+
}
119+
95120
return c, nil
96121
}
97122

98123
// Config holds all the things necessary for the controller to run.
99124
type Config struct {
125+
// GatewayAPIEnabled indicates that the "GatewayAPI" featuregate is enabled.
126+
GatewayAPIEnabled bool
100127
IngressControllerImage string
101128
CanaryImage string
102129
OperatorReleaseVersion string
@@ -159,6 +186,10 @@ func (r *reconciler) Reconcile(ctx context.Context, request reconcile.Request) (
159186
related = append(related, configv1.ObjectReference{
160187
Resource: "namespaces",
161188
Name: state.IngressNamespace.Name,
189+
}, configv1.ObjectReference{
190+
Group: iov1.GroupVersion.Group,
191+
Resource: "dnsrecords",
192+
Namespace: state.IngressNamespace.Name,
162193
})
163194
}
164195
if state.CanaryNamespace != nil {
@@ -167,6 +198,33 @@ func (r *reconciler) Reconcile(ctx context.Context, request reconcile.Request) (
167198
Name: state.CanaryNamespace.Name,
168199
})
169200
}
201+
if r.config.GatewayAPIEnabled {
202+
related = append(related, configv1.ObjectReference{
203+
Group: gatewayapiv1.GroupName,
204+
Resource: "gatewayclasses",
205+
})
206+
if state.haveOSSMSubscription {
207+
subscriptionName := operatorcontroller.ServiceMeshOperatorSubscriptionName()
208+
related = append(related, configv1.ObjectReference{
209+
Group: operatorsv1alpha1.GroupName,
210+
Resource: "subscriptions",
211+
Namespace: subscriptionName.Namespace,
212+
Name: subscriptionName.Name,
213+
})
214+
if state.IngressNamespace != nil {
215+
related = append(related, configv1.ObjectReference{
216+
Group: sailv1.GroupVersion.Group,
217+
Resource: "istios",
218+
Namespace: state.IngressNamespace.Name,
219+
})
220+
related = append(related, configv1.ObjectReference{
221+
Group: gatewayapiv1.GroupName,
222+
Resource: "gateways",
223+
Namespace: state.IngressNamespace.Name,
224+
})
225+
}
226+
}
227+
}
170228

171229
co.Status.RelatedObjects = related
172230

@@ -236,6 +294,8 @@ type operatorState struct {
236294
CanaryNamespace *corev1.Namespace
237295
IngressControllers []operatorv1.IngressController
238296
DNSRecords []iov1.DNSRecord
297+
298+
haveOSSMSubscription bool
239299
}
240300

241301
// getOperatorState gets and returns the resources necessary to compute the
@@ -268,6 +328,18 @@ func (r *reconciler) getOperatorState(ingressNamespace, canaryNamespace string)
268328
state.IngressControllers = ingressList.Items
269329
}
270330

331+
if r.config.GatewayAPIEnabled {
332+
var subscription operatorsv1alpha1.Subscription
333+
subscriptionName := operatorcontroller.ServiceMeshOperatorSubscriptionName()
334+
if err := r.cache.Get(context.TODO(), subscriptionName, &subscription); err != nil {
335+
if !errors.IsNotFound(err) {
336+
return state, fmt.Errorf("failed to get subscription %q: %v", subscriptionName, err)
337+
}
338+
} else {
339+
state.haveOSSMSubscription = true
340+
}
341+
}
342+
271343
return state, nil
272344
}
273345

pkg/operator/operator.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ func New(config operatorconfig.Config, kubeConfig *rest.Config) (*Operator, erro
212212
IngressControllerImage: config.IngressControllerImage,
213213
CanaryImage: config.CanaryImage,
214214
OperatorReleaseVersion: config.OperatorReleaseVersion,
215+
GatewayAPIEnabled: gatewayAPIEnabled,
215216
}); err != nil {
216217
return nil, fmt.Errorf("failed to create status controller: %v", err)
217218
}

test/e2e/operator_test.go

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -219,24 +219,49 @@ func TestClusterOperatorStatusRelatedObjects(t *testing.T) {
219219
Resource: "namespaces",
220220
Name: "openshift-ingress",
221221
},
222+
{
223+
Group: iov1.GroupVersion.Group,
224+
Resource: "dnsrecords",
225+
Namespace: "openshift-ingress",
226+
},
222227
{
223228
Resource: "namespaces",
224229
Name: "openshift-ingress-canary",
225230
},
226231
}
227232

233+
if gatewayAPIEnabled, err := isFeatureGateEnabled(features.FeatureGateGatewayAPI); err != nil {
234+
t.Fatalf("Failed to look up %q featuregate: %v", features.FeatureGateGatewayAPI, err)
235+
} else if gatewayAPIEnabled {
236+
expected = append(expected, configv1.ObjectReference{
237+
Group: "gateway.networking.k8s.io",
238+
Resource: "gatewayclasses",
239+
})
240+
// This test runs before TestGatewayAPI, so we do *not* expect
241+
// to see subscriptions, istios, or gateways in relatedObjects.
242+
}
243+
228244
coName := controller.IngressClusterOperatorName()
229245
err := wait.PollImmediate(1*time.Second, 5*time.Minute, func() (bool, error) {
230246
co := &configv1.ClusterOperator{}
231247
if err := kclient.Get(context.TODO(), coName, co); err != nil {
232-
t.Logf("failed to get ingress cluster operator %s: %v", coName, err)
248+
t.Logf("Failed to get clusteroperator %q: %v", coName.Name, err)
249+
233250
return false, nil
234251
}
235252

236-
return reflect.DeepEqual(expected, co.Status.RelatedObjects), nil
253+
if !reflect.DeepEqual(expected, co.Status.RelatedObjects) {
254+
t.Logf("Expected %+v, found %+v", expected, co.Status.RelatedObjects)
255+
256+
return false, nil
257+
}
258+
259+
t.Log("Found the expected status.relatedObjects")
260+
261+
return true, nil
237262
})
238263
if err != nil {
239-
t.Errorf("did not get expected status related objects: %v", err)
264+
t.Errorf("Did not get expected status related objects: %v", err)
240265
}
241266
}
242267

0 commit comments

Comments
 (0)