Skip to content

Commit 43675ed

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 43675ed

File tree

3 files changed

+97
-2
lines changed

3 files changed

+97
-2
lines changed

pkg/operator/controller/status/controller.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ 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"
13+
gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1"
1114

1215
configv1 "github.com/openshift/api/config/v1"
1316
operatorv1 "github.com/openshift/api/operator/v1"
@@ -29,6 +32,7 @@ import (
2932
"sigs.k8s.io/controller-runtime/pkg/cache"
3033
"sigs.k8s.io/controller-runtime/pkg/client"
3134
"sigs.k8s.io/controller-runtime/pkg/controller"
35+
"sigs.k8s.io/controller-runtime/pkg/event"
3236
"sigs.k8s.io/controller-runtime/pkg/handler"
3337
"sigs.k8s.io/controller-runtime/pkg/manager"
3438
"sigs.k8s.io/controller-runtime/pkg/predicate"
@@ -92,11 +96,33 @@ func New(mgr manager.Manager, config Config) (controller.Controller, error) {
9296
if err := c.Watch(source.Kind[client.Object](operatorCache, &configv1.ClusterOperator{}, handler.EnqueueRequestsFromMapFunc(toDefaultIngressController), predicate.NewPredicateFuncs(isIngressClusterOperator))); err != nil {
9397
return nil, err
9498
}
99+
100+
if config.GatewayAPIEnabled {
101+
if err := c.Watch(source.Kind[client.Object](operatorCache, &operatorsv1alpha1.Subscription{}, handler.EnqueueRequestsFromMapFunc(toDefaultIngressController), predicate.Funcs{
102+
CreateFunc: func(e event.CreateEvent) bool {
103+
return e.Object.GetNamespace() == operatorcontroller.OpenshiftOperatorNamespace
104+
},
105+
UpdateFunc: func(e event.UpdateEvent) bool {
106+
return false
107+
},
108+
DeleteFunc: func(e event.DeleteEvent) bool {
109+
return e.Object.GetNamespace() == operatorcontroller.OpenshiftOperatorNamespace
110+
},
111+
GenericFunc: func(e event.GenericEvent) bool {
112+
return false
113+
},
114+
})); err != nil {
115+
return nil, err
116+
}
117+
}
118+
95119
return c, nil
96120
}
97121

98122
// Config holds all the things necessary for the controller to run.
99123
type Config struct {
124+
// GatewayAPIEnabled indicates that the "GatewayAPI" featuregate is enabled.
125+
GatewayAPIEnabled bool
100126
IngressControllerImage string
101127
CanaryImage string
102128
OperatorReleaseVersion string
@@ -159,6 +185,10 @@ func (r *reconciler) Reconcile(ctx context.Context, request reconcile.Request) (
159185
related = append(related, configv1.ObjectReference{
160186
Resource: "namespaces",
161187
Name: state.IngressNamespace.Name,
188+
}, configv1.ObjectReference{
189+
Group: iov1.GroupVersion.Group,
190+
Resource: "dnsrecords",
191+
Namespace: state.IngressNamespace.Name,
162192
})
163193
}
164194
if state.CanaryNamespace != nil {
@@ -167,6 +197,33 @@ func (r *reconciler) Reconcile(ctx context.Context, request reconcile.Request) (
167197
Name: state.CanaryNamespace.Name,
168198
})
169199
}
200+
if r.config.GatewayAPIEnabled {
201+
related = append(related, configv1.ObjectReference{
202+
Group: gatewayapiv1.GroupName,
203+
Resource: "gatewayclasses",
204+
})
205+
if state.haveOSSMSubscription {
206+
subscriptionName := operatorcontroller.ServiceMeshOperatorSubscriptionName()
207+
related = append(related, configv1.ObjectReference{
208+
Group: operatorsv1alpha1.GroupName,
209+
Resource: "subscriptions",
210+
Namespace: subscriptionName.Namespace,
211+
Name: subscriptionName.Name,
212+
})
213+
if state.IngressNamespace != nil {
214+
related = append(related, configv1.ObjectReference{
215+
Group: sailv1.GroupVersion.Group,
216+
Resource: "istios",
217+
Namespace: state.IngressNamespace.Name,
218+
})
219+
related = append(related, configv1.ObjectReference{
220+
Group: gatewayapiv1.GroupName,
221+
Resource: "gateways",
222+
Namespace: state.IngressNamespace.Name,
223+
})
224+
}
225+
}
226+
}
170227

171228
co.Status.RelatedObjects = related
172229

@@ -236,6 +293,8 @@ type operatorState struct {
236293
CanaryNamespace *corev1.Namespace
237294
IngressControllers []operatorv1.IngressController
238295
DNSRecords []iov1.DNSRecord
296+
297+
haveOSSMSubscription bool
239298
}
240299

241300
// getOperatorState gets and returns the resources necessary to compute the
@@ -268,6 +327,18 @@ func (r *reconciler) getOperatorState(ingressNamespace, canaryNamespace string)
268327
state.IngressControllers = ingressList.Items
269328
}
270329

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

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: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,21 +219,44 @@ 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+
return true, nil
237260
})
238261
if err != nil {
239262
t.Errorf("did not get expected status related objects: %v", err)

0 commit comments

Comments
 (0)