Skip to content

Commit 2006957

Browse files
committed
Network: gateway routes
1 parent fd4eeb0 commit 2006957

File tree

10 files changed

+310
-19
lines changed

10 files changed

+310
-19
lines changed

.github/workflows/integration.yml

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ on:
88
- network-general
99
- network-external
1010
- network-internal
11+
- frc/gatewayroute
1112
repository_dispatch:
1213
types:
1314
- test-command

cmd/gateway/geneve/main.go

-15
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ import (
3333
networkingv1alpha1 "github.com/liqotech/liqo/apis/networking/v1alpha1"
3434
"github.com/liqotech/liqo/pkg/gateway"
3535
"github.com/liqotech/liqo/pkg/gateway/fabric/geneve"
36-
"github.com/liqotech/liqo/pkg/route"
3736
flagsutils "github.com/liqotech/liqo/pkg/utils/flags"
3837
"github.com/liqotech/liqo/pkg/utils/mapper"
3938
"github.com/liqotech/liqo/pkg/utils/restcfg"
@@ -113,20 +112,6 @@ func run(cmd *cobra.Command, _ []string) error {
113112
return fmt.Errorf("unable to create manager: %w", err)
114113
}
115114

116-
rcr, err := route.NewRouteConfigurationReconcilerWithoutFinalizer(
117-
mgr.GetClient(),
118-
mgr.GetScheme(),
119-
mgr.GetEventRecorderFor("routeconfiguration-controller"),
120-
geneve.ForgeRouteTargetLabels(options.GwOptions.Name),
121-
)
122-
if err != nil {
123-
return fmt.Errorf("unable to create routeconfiguration reconciler: %w", err)
124-
}
125-
126-
if err := rcr.SetupWithManager(mgr); err != nil {
127-
return fmt.Errorf("unable to setup routeconfiguration reconciler: %w", err)
128-
}
129-
130115
inr, err := geneve.NewInternalNodeReconciler(
131116
mgr.GetClient(),
132117
mgr.GetScheme(),

cmd/gateway/main.go

+16
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ import (
3737
"github.com/liqotech/liqo/pkg/gateway"
3838
"github.com/liqotech/liqo/pkg/gateway/connection"
3939
"github.com/liqotech/liqo/pkg/gateway/connection/conncheck"
40+
"github.com/liqotech/liqo/pkg/gateway/fabric/geneve"
4041
"github.com/liqotech/liqo/pkg/gateway/remapping"
42+
"github.com/liqotech/liqo/pkg/route"
4143
flagsutils "github.com/liqotech/liqo/pkg/utils/flags"
4244
"github.com/liqotech/liqo/pkg/utils/mapper"
4345
"github.com/liqotech/liqo/pkg/utils/restcfg"
@@ -151,6 +153,20 @@ func run(cmd *cobra.Command, _ []string) error {
151153
}
152154
}
153155

156+
rcr, err := route.NewRouteConfigurationReconcilerWithoutFinalizer(
157+
mgr.GetClient(),
158+
mgr.GetScheme(),
159+
mgr.GetEventRecorderFor("routeconfiguration-controller"),
160+
geneve.ForgeRouteTargetLabels(connoptions.GwOptions.Name),
161+
)
162+
if err != nil {
163+
return fmt.Errorf("unable to create routeconfiguration reconciler: %w", err)
164+
}
165+
166+
if err := rcr.SetupWithManager(mgr); err != nil {
167+
return fmt.Errorf("unable to setup routeconfiguration reconciler: %w", err)
168+
}
169+
154170
// Setup the firewall configuration controller.
155171
fwcr, err := firewall.NewFirewallConfigurationReconcilerWithoutFinalizer(
156172
mgr.GetClient(),

cmd/liqo-controller-manager/main.go

+11-2
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ import (
6868
clientoperator "github.com/liqotech/liqo/pkg/liqo-controller-manager/external-network/client-operator"
6969
configurationcontroller "github.com/liqotech/liqo/pkg/liqo-controller-manager/external-network/configuration-controller"
7070
externalnetworkcontroller "github.com/liqotech/liqo/pkg/liqo-controller-manager/external-network/externalnetwork-controller"
71+
externalnetworkroute "github.com/liqotech/liqo/pkg/liqo-controller-manager/external-network/route"
7172
serveroperator "github.com/liqotech/liqo/pkg/liqo-controller-manager/external-network/server-operator"
7273
wggatewaycontrollers "github.com/liqotech/liqo/pkg/liqo-controller-manager/external-network/wireguard"
7374
foreignclusteroperator "github.com/liqotech/liqo/pkg/liqo-controller-manager/foreign-cluster-operator"
@@ -676,12 +677,20 @@ func main() {
676677
os.Exit(1)
677678
}
678679

679-
cfgr := configurationcontroller.NewConfigurationReconciler(mgr.GetClient(), mgr.GetScheme(), mgr.GetEventRecorderFor("configuration-controller"))
680-
if err = cfgr.SetupWithManager(mgr); err != nil {
680+
intcfgr := configurationcontroller.NewConfigurationReconciler(mgr.GetClient(), mgr.GetScheme(),
681+
mgr.GetEventRecorderFor("internal.-configuration-controller"))
682+
if err = intcfgr.SetupWithManager(mgr); err != nil {
681683
klog.Errorf("unable to create controller ConfigurationReconciler: %s", err)
682684
os.Exit(1)
683685
}
684686

687+
extcfg := externalnetworkroute.NewConfigurationReconciler(mgr.GetClient(), mgr.GetScheme(),
688+
mgr.GetEventRecorderFor("external-configuration-controller"))
689+
if err = extcfg.SetupWithManager(mgr); err != nil {
690+
klog.Errorf("unable to create controller ExternalConfigurationReconciler: %s", err)
691+
os.Exit(1)
692+
}
693+
685694
wgServerRec := wggatewaycontrollers.NewWgGatewayServerReconciler(
686695
mgr.GetClient(), mgr.GetScheme(), auxmgrExtNetworkPods.GetClient(), wgGatewayServerClusterRoleName)
687696
if err = wgServerRec.SetupWithManager(mgr); err != nil {

pkg/firewall/firewallconfiguration_controller.go

+3
Original file line numberDiff line numberDiff line change
@@ -149,11 +149,14 @@ func (r *FirewallConfigurationReconciler) Reconcile(ctx context.Context, req ctr
149149
return ctrl.Result{}, err
150150
}
151151

152+
klog.Infof("Applied firewallconfiguration %s", req.String())
153+
152154
return ctrl.Result{}, nil
153155
}
154156

155157
// SetupWithManager register the FirewallConfigurationReconciler to the manager.
156158
func (r *FirewallConfigurationReconciler) SetupWithManager(mgr ctrl.Manager) error {
159+
klog.Infof("Starting FirewallConfiguration controller with labels %v", r.Labels)
157160
filterByLabelsPredicate, err := predicate.LabelSelectorPredicate(metav1.LabelSelector{MatchLabels: r.Labels})
158161
if err != nil {
159162
return err
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
// Copyright 2019-2024 The Liqo Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package route
16+
17+
import (
18+
"context"
19+
"fmt"
20+
21+
apierrors "k8s.io/apimachinery/pkg/api/errors"
22+
"k8s.io/apimachinery/pkg/runtime"
23+
"k8s.io/client-go/tools/record"
24+
"k8s.io/klog/v2"
25+
ctrl "sigs.k8s.io/controller-runtime"
26+
"sigs.k8s.io/controller-runtime/pkg/client"
27+
"sigs.k8s.io/controller-runtime/pkg/handler"
28+
"sigs.k8s.io/controller-runtime/pkg/reconcile"
29+
30+
networkingv1alpha1 "github.com/liqotech/liqo/apis/networking/v1alpha1"
31+
"github.com/liqotech/liqo/pkg/consts"
32+
"github.com/liqotech/liqo/pkg/utils/getters"
33+
)
34+
35+
// ConfigurationReconciler manage Configuration.
36+
type ConfigurationReconciler struct {
37+
client.Client
38+
Scheme *runtime.Scheme
39+
EventsRecorder record.EventRecorder
40+
}
41+
42+
// NewConfigurationReconciler returns a new ConfigurationReconciler.
43+
func NewConfigurationReconciler(cl client.Client, s *runtime.Scheme,
44+
er record.EventRecorder) *ConfigurationReconciler {
45+
return &ConfigurationReconciler{
46+
Client: cl,
47+
Scheme: s,
48+
EventsRecorder: er,
49+
}
50+
}
51+
52+
// cluster-role
53+
// +kubebuilder:rbac:groups=networking.liqo.io,resources=configurations,verbs=get;list;watch;update;patch
54+
// +kubebuilder:rbac:groups=networking.liqo.io,resources=routeconfigurations,verbs=get;list;watch;update;patch;create;delete
55+
56+
// Reconcile manage Configurations.
57+
func (r *ConfigurationReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
58+
var err error
59+
configuration := &networkingv1alpha1.Configuration{}
60+
if err = r.Get(ctx, req.NamespacedName, configuration); err != nil {
61+
if apierrors.IsNotFound(err) {
62+
klog.Infof("There is no configuration %s", req.String())
63+
return ctrl.Result{}, nil
64+
}
65+
return ctrl.Result{}, fmt.Errorf("unable to get the configuration %q: %w", req.NamespacedName, err)
66+
}
67+
68+
klog.V(4).Infof("Reconciling configuration %s", req.String())
69+
70+
return ctrl.Result{}, enforeRouteConfigurationPresence(ctx, r.Client, r.Scheme, configuration)
71+
}
72+
73+
// SetupWithManager register the ConfigurationReconciler to the manager.
74+
func (r *ConfigurationReconciler) SetupWithManager(mgr ctrl.Manager) error {
75+
return ctrl.NewControllerManagedBy(mgr).
76+
For(&networkingv1alpha1.Configuration{}).
77+
Watches(
78+
&networkingv1alpha1.GatewayServer{},
79+
handler.EnqueueRequestsFromMapFunc(r.configurationEnqueuerByRemoteID()),
80+
).
81+
Watches(
82+
&networkingv1alpha1.GatewayClient{},
83+
handler.EnqueueRequestsFromMapFunc(r.configurationEnqueuerByRemoteID()),
84+
).
85+
Complete(r)
86+
}
87+
88+
func (r *ConfigurationReconciler) configurationEnqueuerByRemoteID() handler.MapFunc {
89+
return func(ctx context.Context, obj client.Object) []reconcile.Request {
90+
labels := obj.GetLabels()
91+
if labels == nil {
92+
klog.Errorf("unable to get the labels of gateway %s", obj.GetName())
93+
return nil
94+
}
95+
remoteID, ok := labels[consts.RemoteClusterID]
96+
if !ok {
97+
klog.Errorf("unable to get the remote cluster ID from the labels of gateway %s", obj.GetName())
98+
return nil
99+
}
100+
cfg, err := getters.GetConfigurationByClusterID(ctx, r.Client, remoteID)
101+
if err != nil {
102+
klog.Errorf("unable to get the configuration for cluster %s: %s", remoteID, err)
103+
return nil
104+
}
105+
return []reconcile.Request{{NamespacedName: client.ObjectKeyFromObject(cfg)}}
106+
}
107+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright 2019-2024 The Liqo Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
// Package route contains the logic to manage the routesconfiguration for the external-network.
16+
package route
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
// Copyright 2019-2024 The Liqo Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package route
16+
17+
import (
18+
"context"
19+
"fmt"
20+
21+
kerrors "k8s.io/apimachinery/pkg/api/errors"
22+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
23+
"k8s.io/apimachinery/pkg/runtime"
24+
"k8s.io/utils/ptr"
25+
"sigs.k8s.io/controller-runtime/pkg/client"
26+
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
27+
28+
"github.com/liqotech/liqo/apis/discovery/v1alpha1"
29+
networkingv1alpha1 "github.com/liqotech/liqo/apis/networking/v1alpha1"
30+
"github.com/liqotech/liqo/pkg/consts"
31+
"github.com/liqotech/liqo/pkg/gateway"
32+
"github.com/liqotech/liqo/pkg/gateway/fabric/geneve"
33+
"github.com/liqotech/liqo/pkg/gateway/tunnel/common"
34+
"github.com/liqotech/liqo/pkg/utils/getters"
35+
)
36+
37+
// GetRemoteClusterID returns the remote cluster ID of the Configuration.
38+
func GetRemoteClusterID(cfg *networkingv1alpha1.Configuration) (string, error) {
39+
if cfg.GetLabels() == nil {
40+
return "", fmt.Errorf("configuration %s/%s has no labels", cfg.Namespace, cfg.Name)
41+
}
42+
remoteID, ok := cfg.GetLabels()[consts.RemoteClusterID]
43+
if !ok {
44+
return "", fmt.Errorf("configuration %s/%s has no remote cluster ID label", cfg.Namespace, cfg.Name)
45+
}
46+
return remoteID, nil
47+
}
48+
49+
// enforceRouteConfigurationPresence creates or updates a RouteConfiguration object.
50+
func enforeRouteConfigurationPresence(ctx context.Context, cl client.Client, scheme *runtime.Scheme,
51+
cfg *networkingv1alpha1.Configuration) error {
52+
remoteClusterID, err := GetRemoteClusterID(cfg)
53+
if err != nil {
54+
return err
55+
}
56+
57+
mode, err := GetGatewayMode(ctx, cl, remoteClusterID)
58+
if err != nil {
59+
return err
60+
}
61+
// If the Gateway is not already present, we are not able to understand if it will be a server or a client
62+
if mode == "" {
63+
return nil
64+
}
65+
66+
remoteInterfaceIP, err := common.GetRemoteInterfaceIP(mode)
67+
if err != nil {
68+
return err
69+
}
70+
71+
routecfg := &networkingv1alpha1.RouteConfiguration{
72+
ObjectMeta: metav1.ObjectMeta{
73+
Name: fmt.Sprintf("%s-gw-ext", cfg.Name),
74+
Namespace: cfg.Namespace,
75+
},
76+
}
77+
78+
_, err = controllerutil.CreateOrUpdate(ctx, cl, routecfg,
79+
forgeMutateRouteConfiguration(cfg, routecfg, scheme, remoteClusterID, remoteInterfaceIP))
80+
return err
81+
}
82+
83+
// forgeMutateRouteConfiguration mutates a RouteConfiguration object.
84+
func forgeMutateRouteConfiguration(cfg *networkingv1alpha1.Configuration,
85+
routecfg *networkingv1alpha1.RouteConfiguration, scheme *runtime.Scheme, remoteClusterID string, remoteInterfaceIP string) func() error {
86+
return func() error {
87+
var err error
88+
89+
if err = controllerutil.SetOwnerReference(cfg, routecfg, scheme); err != nil {
90+
return err
91+
}
92+
93+
routecfg.ObjectMeta.Labels = geneve.ForgeRouteTargetLabels(remoteClusterID)
94+
if err != nil {
95+
return err
96+
}
97+
98+
routecfg.Spec = networkingv1alpha1.RouteConfigurationSpec{
99+
Table: networkingv1alpha1.Table{
100+
Name: cfg.Name,
101+
Rules: []networkingv1alpha1.Rule{
102+
{
103+
Dst: &cfg.Status.Remote.CIDR.Pod,
104+
Routes: []networkingv1alpha1.Route{
105+
{
106+
Dst: &cfg.Status.Remote.CIDR.Pod,
107+
Gw: ptr.To(networkingv1alpha1.IP(remoteInterfaceIP)),
108+
},
109+
},
110+
},
111+
{
112+
Dst: &cfg.Status.Remote.CIDR.External,
113+
Routes: []networkingv1alpha1.Route{
114+
{
115+
Dst: &cfg.Status.Remote.CIDR.External,
116+
Gw: ptr.To(networkingv1alpha1.IP(remoteInterfaceIP)),
117+
},
118+
},
119+
},
120+
},
121+
},
122+
}
123+
return nil
124+
}
125+
}
126+
127+
// GetGatewayMode returns the mode of the Gateway related to the Configuration.
128+
func GetGatewayMode(ctx context.Context, cl client.Client, remoteClusterID string) (gateway.Mode, error) {
129+
gwclient, err := getters.GetGatewayClientByClusterID(ctx, cl, &v1alpha1.ClusterIdentity{ClusterID: remoteClusterID})
130+
if err != nil && !kerrors.IsNotFound(err) {
131+
return "", err
132+
}
133+
134+
gwserver, err := getters.GetGatewayServerByClusterID(ctx, cl, &v1alpha1.ClusterIdentity{ClusterID: remoteClusterID})
135+
if err != nil && !kerrors.IsNotFound(err) {
136+
return "", err
137+
}
138+
139+
switch {
140+
case gwclient == nil && gwserver == nil:
141+
return "", nil
142+
case gwclient != nil && gwserver != nil:
143+
return "", fmt.Errorf("multiple Gateways found for cluster %s", remoteClusterID)
144+
case gwclient == nil && gwserver != nil:
145+
return gateway.ModeServer, nil
146+
case gwclient != nil && gwserver == nil:
147+
return gateway.ModeClient, nil
148+
}
149+
150+
return "", fmt.Errorf("unable to determine Gateway mode for cluster %s", remoteClusterID)
151+
}

pkg/liqo-controller-manager/internal-network/internalfabric-controller/internalfabric_controller.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ func (r *InternalFabricReconciler) ensureRouteConfiguration(ctx context.Context,
111111

112112
route := &networkingv1alpha1.RouteConfiguration{
113113
ObjectMeta: metav1.ObjectMeta{
114-
Name: internalFabric.Name,
114+
Name: fmt.Sprintf("%s-node-gw", internalFabric.Name),
115115
Namespace: internalFabric.Namespace,
116116
},
117117
}

0 commit comments

Comments
 (0)