-
Notifications
You must be signed in to change notification settings - Fork 110
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
24 changed files
with
1,183 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -90,8 +90,8 @@ jobs: | |
- metric-agent | ||
- telemetry | ||
- proxy | ||
- gateway/wireguard | ||
steps: | ||
|
||
- name: Set up QEMU | ||
uses: docker/[email protected] | ||
with: | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
FROM golang:1.21 as goBuilder | ||
WORKDIR /tmp/builder | ||
|
||
COPY go.mod ./go.mod | ||
COPY go.sum ./go.sum | ||
RUN go mod download | ||
|
||
COPY . ./ | ||
RUN CGO_ENABLED=0 GOOS=linux GOARCH=$(go env GOARCH) go build -ldflags="-s -w" ./cmd/gateway/wireguard | ||
|
||
|
||
FROM alpine:3.18 | ||
|
||
RUN apk update && \ | ||
apk add iptables bash wireguard-tools tcpdump conntrack-tools curl iputils && \ | ||
rm -rf /var/cache/apk/* | ||
|
||
COPY --from=goBuilder /tmp/builder/wireguard /usr/bin/liqo-wireguard | ||
|
||
ENTRYPOINT [ "/usr/bin/liqo-wireguard" ] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
// Copyright 2019-2023 The Liqo Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
// Package wireguard contains the logic to configure the Wireguard interface. | ||
package main | ||
|
||
import ( | ||
"flag" | ||
"fmt" | ||
"net" | ||
"os" | ||
|
||
"github.com/spf13/cobra" | ||
corev1 "k8s.io/api/core/v1" | ||
"k8s.io/apimachinery/pkg/runtime" | ||
"k8s.io/client-go/tools/leaderelection/resourcelock" | ||
"k8s.io/klog/v2" | ||
ctrl "sigs.k8s.io/controller-runtime" | ||
"sigs.k8s.io/controller-runtime/pkg/client" | ||
"sigs.k8s.io/controller-runtime/pkg/client/config" | ||
"sigs.k8s.io/controller-runtime/pkg/event" | ||
"sigs.k8s.io/controller-runtime/pkg/log" | ||
|
||
ipamv1alpha1 "github.com/liqotech/liqo/apis/ipam/v1alpha1" | ||
networkingv1alpha1 "github.com/liqotech/liqo/apis/networking/v1alpha1" | ||
"github.com/liqotech/liqo/pkg/gateway/tunnel/common" | ||
"github.com/liqotech/liqo/pkg/gateway/tunnel/wireguard" | ||
flagsutils "github.com/liqotech/liqo/pkg/utils/flags" | ||
"github.com/liqotech/liqo/pkg/utils/mapper" | ||
"github.com/liqotech/liqo/pkg/utils/restcfg" | ||
) | ||
|
||
var ( | ||
addToSchemeFunctions = []func(*runtime.Scheme) error{ | ||
corev1.AddToScheme, | ||
networkingv1alpha1.AddToScheme, | ||
ipamv1alpha1.AddToScheme, | ||
} | ||
options = wireguard.NewOptions() | ||
) | ||
|
||
func main() { | ||
var cmd = cobra.Command{ | ||
Use: "liqo-wireguard", | ||
RunE: run, | ||
} | ||
|
||
legacyflags := flag.NewFlagSet("legacy", flag.ExitOnError) | ||
restcfg.InitFlags(legacyflags) | ||
klog.InitFlags(legacyflags) | ||
flagsutils.FromFlagToPflag(legacyflags, cmd.Flags()) | ||
|
||
wireguard.InitFlags(cmd.Flags(), options) | ||
if err := wireguard.MarkFlagsRequired(&cmd, options); err != nil { | ||
klog.Error(err) | ||
os.Exit(1) | ||
} | ||
|
||
if err := cmd.Execute(); err != nil { | ||
klog.Error(err) | ||
os.Exit(1) | ||
} | ||
} | ||
|
||
func run(cmd *cobra.Command, _ []string) error { | ||
var err error | ||
scheme := runtime.NewScheme() | ||
|
||
// Adds the APIs to the scheme. | ||
for _, addToScheme := range addToSchemeFunctions { | ||
if err = addToScheme(scheme); err != nil { | ||
return fmt.Errorf("unable to add scheme: %w", err) | ||
} | ||
} | ||
|
||
// Set controller-runtime logger. | ||
log.SetLogger(klog.NewKlogr()) | ||
|
||
// Get the rest config. | ||
cfg := config.GetConfigOrDie() | ||
|
||
// Create the client. This client should be used only outside the reconciler. | ||
// This client don't need a cache. | ||
cl, err := client.New(cfg, client.Options{ | ||
Scheme: scheme, | ||
}) | ||
if err != nil { | ||
return fmt.Errorf("unable to create client: %w", err) | ||
} | ||
|
||
// Create the manager. | ||
mgr, err := ctrl.NewManager(cfg, ctrl.Options{ | ||
MapperProvider: mapper.LiqoMapperProvider(scheme), | ||
Scheme: scheme, | ||
Namespace: options.Namespace, | ||
MetricsBindAddress: options.MetricsAddress, | ||
HealthProbeBindAddress: options.ProbeAddr, | ||
LeaderElection: options.LeaderElection, | ||
LeaderElectionID: fmt.Sprintf( | ||
"%s.%s.%s.wgtunnel.liqo.io", | ||
wireguard.GenerateResourceName(options.Name), options.Namespace, options.Mode, | ||
), | ||
LeaderElectionNamespace: options.Namespace, | ||
LeaderElectionReleaseOnCancel: true, | ||
LeaderElectionResourceLock: resourcelock.LeasesResourceLock, | ||
LeaseDuration: &options.LeaderElectionLeaseDuration, | ||
RenewDeadline: &options.LeaderElectionRenewDeadline, | ||
RetryPeriod: &options.LeaderElectionRetryPeriod, | ||
}) | ||
if err != nil { | ||
return fmt.Errorf("unable to create manager: %w", err) | ||
} | ||
|
||
// Setup the controller. | ||
pkr, err := wireguard.NewPublicKeysReconciler( | ||
mgr.GetClient(), | ||
mgr.GetScheme(), | ||
mgr.GetEventRecorderFor("public-keys-controller"), | ||
options, | ||
) | ||
if err != nil { | ||
return fmt.Errorf("unable to create public keys reconciler: %w", err) | ||
} | ||
|
||
dnsChan := make(chan event.GenericEvent) | ||
if options.Mode == common.ModeClient { | ||
if wireguard.IsDNSRoutineRequired(options) { | ||
go wireguard.StartDNSRoutine(cmd.Context(), dnsChan, options) | ||
klog.Infof("Starting DNS routine: resolving the endpoint address every %s", options.DNSCheckInterval.String()) | ||
} else { | ||
options.EndpointIP = net.ParseIP(options.EndpointAddress) | ||
klog.Infof("Setting static endpoint IP: %s", options.EndpointIP.String()) | ||
} | ||
} | ||
|
||
// Setup the controller. | ||
if err = pkr.SetupWithManager(mgr, dnsChan); err != nil { | ||
return fmt.Errorf("unable to setup public keys reconciler: %w", err) | ||
} | ||
|
||
// Ensure presence of Secret with private and public keys. | ||
if err = wireguard.EnsureKeysSecret(cmd.Context(), cl, options); err != nil { | ||
return fmt.Errorf("unable to manage wireguard keys secret: %w", err) | ||
} | ||
|
||
// Create the wg-liqo interface and init the wireguard configuration depending on the mode (client/server). | ||
if err := wireguard.InitWireguardLink(options); err != nil { | ||
return fmt.Errorf("unable to init wireguard link: %w", err) | ||
} | ||
|
||
// Start the manager. | ||
return mgr.Start(cmd.Context()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
rules: | ||
- apiGroups: | ||
- "" | ||
resources: | ||
- secrets | ||
verbs: | ||
- create | ||
- delete | ||
- get | ||
- list | ||
- update | ||
- apiGroups: | ||
- networking.liqo.io | ||
resources: | ||
- publickeys | ||
verbs: | ||
- create | ||
- delete | ||
- get | ||
- list | ||
- update |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
--- | ||
{{- $gatewayConfig := (merge (dict "name" "gateway" "module" "networking") .) -}} | ||
|
||
{{- if .Values.networking.internal }} | ||
|
||
apiVersion: rbac.authorization.k8s.io/v1 | ||
kind: ClusterRole | ||
metadata: | ||
name: {{ include "liqo.prefixedName" $gatewayConfig }} | ||
labels: | ||
{{- include "liqo.labels" $gatewayConfig | nindent 4 }} | ||
{{ .Files.Get (include "liqo.cluster-role-filename" (dict "prefix" ( include "liqo.prefixedName" $gatewayConfig))) }} | ||
|
||
{{- end }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// Copyright 2019-2023 The Liqo Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
// Package common contains the common functions used by the tunneling package. | ||
package common |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// Copyright 2019-2023 The Liqo Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package common | ||
|
||
import "github.com/vishvananda/netlink" | ||
|
||
// AddAddress adds an IP address to the Wireguard interface. | ||
func AddAddress(link netlink.Link, ip string) error { | ||
addr, err := netlink.ParseAddr(ip) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return netlink.AddrAdd(link, addr) | ||
} | ||
|
||
// GetLink returns the Wireguard interface. | ||
func GetLink(name string) (netlink.Link, error) { | ||
return netlink.LinkByName(name) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
// Copyright 2019-2023 The Liqo Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package common | ||
|
||
import ( | ||
"fmt" | ||
) | ||
|
||
// Mode is the mode in which the wireguard interface is configured. | ||
type Mode string | ||
|
||
const ( | ||
// ModeServer is the mode in which the wireguard interface is configured as a server. | ||
ModeServer Mode = "server" | ||
// ModeClient is the mode in which the wireguard interface is configured as a client. | ||
ModeClient Mode = "client" | ||
) | ||
|
||
// String returns the string representation of the mode. | ||
func (m Mode) String() string { | ||
return string(m) | ||
} | ||
|
||
// Set sets the value of the mode. | ||
func (m *Mode) Set(value string) error { | ||
if value == "" { | ||
return fmt.Errorf("mode cannot be empty") | ||
} | ||
if value != ModeServer.String() && value != ModeClient.String() { | ||
return fmt.Errorf("invalid mode %q", value) | ||
} | ||
*m = Mode(value) | ||
return nil | ||
} | ||
|
||
// Type returns the type of the mode. | ||
func (m *Mode) Type() string { | ||
return "string" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
// Copyright 2019-2023 The Liqo Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package wireguard | ||
|
||
import ( | ||
"net" | ||
|
||
"golang.zx2c4.com/wireguard/wgctrl" | ||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes" | ||
|
||
"github.com/liqotech/liqo/pkg/gateway/tunnel/common" | ||
) | ||
|
||
func configureDevice(wgcl *wgctrl.Client, options *Options, peerPubKey wgtypes.Key) error { | ||
confdev := wgtypes.Config{ | ||
PrivateKey: &options.PrivateKey, | ||
ListenPort: nil, | ||
Peers: []wgtypes.PeerConfig{ | ||
{ | ||
PublicKey: peerPubKey, | ||
AllowedIPs: []net.IPNet{{IP: net.IP{0, 0, 0, 0}, Mask: net.CIDRMask(0, 32)}}, | ||
}, | ||
}, | ||
ReplacePeers: true, | ||
} | ||
|
||
switch options.Mode { | ||
case common.ModeServer: | ||
confdev.ListenPort = &options.ListenPort | ||
case common.ModeClient: | ||
confdev.Peers[0].Endpoint = &net.UDPAddr{ | ||
IP: options.EndpointIP, | ||
Port: options.EndpointPort, | ||
} | ||
} | ||
|
||
return wgcl.ConfigureDevice(options.InterfaceName, confdev) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
// Copyright 2019-2023 The Liqo Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package wireguard | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"net" | ||
"os" | ||
|
||
"k8s.io/apimachinery/pkg/labels" | ||
"k8s.io/apimachinery/pkg/types" | ||
"k8s.io/apimachinery/pkg/util/wait" | ||
"k8s.io/klog/v2" | ||
"sigs.k8s.io/controller-runtime/pkg/client" | ||
"sigs.k8s.io/controller-runtime/pkg/event" | ||
"sigs.k8s.io/controller-runtime/pkg/handler" | ||
"sigs.k8s.io/controller-runtime/pkg/reconcile" | ||
"sigs.k8s.io/controller-runtime/pkg/source" | ||
|
||
"github.com/liqotech/liqo/pkg/consts" | ||
"github.com/liqotech/liqo/pkg/gateway/tunnel/common" | ||
"github.com/liqotech/liqo/pkg/utils/getters" | ||
) | ||
|
||
// StartDNSRoutine run a routine which periodically resolves the DNS associated to the wireguard client endpoint. | ||
// The DNS is resolved every 5 minutes. | ||
// If the DNS changed a new publickkeys-controller reconcile is triggered through a generic event. | ||
func StartDNSRoutine(ctx context.Context, ch chan event.GenericEvent, opts *Options) { | ||
err := wait.PollUntilContextCancel(ctx, opts.DNSCheckInterval, true, func(ctx context.Context) (done bool, err error) { | ||
ips, err := net.LookupIP(opts.EndpointAddress) | ||
if err != nil { | ||
dnsErr := &net.DNSError{} | ||
if !errors.As(err, &dnsErr) { | ||
return false, err | ||
} | ||
switch { | ||
case dnsErr.IsNotFound: | ||
klog.Warningf("DNS %q not found", opts.EndpointAddress) | ||
return false, nil | ||
case dnsErr.IsTimeout: | ||
klog.Warningf("DNS %q timeout", opts.EndpointAddress) | ||
return false, nil | ||
default: | ||
return false, err | ||
} | ||
} | ||
|
||
// Checks if the DNS resolution has changed | ||
for _, ip := range ips { | ||
if opts.EndpointIP.Equal(ip) { | ||
return false, nil | ||
} | ||
} | ||
|
||
klog.Infof("DNS %q resolved to %q: updating endpoint", opts.EndpointAddress, ips[0]) | ||
|
||
// Copies the new IPs to store for the next check | ||
opts.EndpointIPMutex.Lock() | ||
defer opts.EndpointIPMutex.Unlock() | ||
if len(ips) == 0 { | ||
return false, nil | ||
} | ||
opts.EndpointIP = ips[0] | ||
|
||
// Triggers a new reconcile | ||
ch <- event.GenericEvent{} | ||
return false, nil | ||
}) | ||
if err != nil { | ||
klog.Error(err) | ||
os.Exit(1) | ||
} | ||
} | ||
|
||
// IsDNSRoutineRequired checks if the client endpoint is a DNS. | ||
// If it is a DNS the DNS routine is required. | ||
func IsDNSRoutineRequired(opts *Options) bool { | ||
if opts.Mode != common.ModeClient { | ||
return false | ||
} | ||
return net.ParseIP(opts.EndpointAddress) == nil | ||
} | ||
|
||
// NewDNSSource creates a new Source for the DNS watcher. | ||
func NewDNSSource(src <-chan event.GenericEvent) *source.Channel { | ||
return &source.Channel{ | ||
Source: src, | ||
} | ||
} | ||
|
||
// NewDNSEventHandler creates a new EventHandler. | ||
func NewDNSEventHandler(cl client.Client, opts *Options) handler.EventHandler { | ||
return handler.EnqueueRequestsFromMapFunc( | ||
func(ctx context.Context, _ client.Object) []reconcile.Request { | ||
labelSet := labels.Set{ | ||
string(LabelsMode): string(opts.Mode), | ||
string(consts.RemoteClusterID): opts.RemoteClusterID, | ||
} | ||
list, err := getters.ListPublicKeysByLabel(ctx, cl, opts.Namespace, labels.SelectorFromSet(labelSet)) | ||
if err != nil { | ||
klog.Error(err) | ||
} | ||
if len(list.Items) == 0 { | ||
klog.Errorf("There are no public keys with label %s", labelSet) | ||
return nil | ||
} | ||
if len(list.Items) != 1 { | ||
klog.Errorf("There are %d public keys with label %s", len(list.Items), labelSet) | ||
return nil | ||
} | ||
return []reconcile.Request{ | ||
{NamespacedName: types.NamespacedName{Name: list.Items[0].Name, Namespace: list.Items[0].Namespace}}, | ||
} | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// Copyright 2019-2023 The Liqo Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
// Package wireguard contains the implementation of the wireguard tunnel. | ||
package wireguard |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
// Copyright 2019-2023 The Liqo Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package wireguard | ||
|
||
import ( | ||
"time" | ||
|
||
"github.com/spf13/cobra" | ||
"github.com/spf13/pflag" | ||
|
||
"github.com/liqotech/liqo/pkg/gateway/tunnel/common" | ||
) | ||
|
||
// FlagName is the type for the name of the flags. | ||
type FlagName string | ||
|
||
func (fn FlagName) String() string { | ||
return string(fn) | ||
} | ||
|
||
const ( | ||
// FlagNameName is the name of the WgGateway resource. | ||
FlagNameName FlagName = "name" | ||
// FlagNameNamespace is the namespace WgGateway resource. | ||
FlagNameNamespace FlagName = "namespace" | ||
// FlagNameRemoteClusterID is the clusterID of the remote cluster. | ||
FlagNameRemoteClusterID FlagName = "remote-cluster-id" | ||
// FlagNameGatewayUID is the UID of the wireguard gateway. | ||
FlagNameGatewayUID FlagName = "gateway-uid" | ||
|
||
// FlagNameMode is the mode in which the wireguard interface is configured. | ||
FlagNameMode FlagName = "mode" | ||
// FlagNameMTU is the MTU for the wireguard interface. | ||
FlagNameMTU FlagName = "mtu" | ||
// FlagNameListenPort is the listen port for the wireguard interface. | ||
FlagNameListenPort FlagName = "listen-port" | ||
// FlagNameInterfaceName is the name of the wireguard interface. | ||
FlagNameInterfaceName FlagName = "interface-name" | ||
// FlagNameInterfaceIP is the IP of the wireguard interface. | ||
FlagNameInterfaceIP FlagName = "interface-ip" | ||
// FlagNameEndpointAddress is the address of the endpoint for the wireguard interface. | ||
FlagNameEndpointAddress FlagName = "endpoint-address" | ||
// FlagNameEndpointPort is the port of the endpoint for the wireguard interface. | ||
FlagNameEndpointPort FlagName = "endpoint-port" | ||
|
||
// FlagNameDNSCheckInterval is the interval between two DNS checks. | ||
FlagNameDNSCheckInterval FlagName = "dns-check-interval" | ||
|
||
// FlagNameLeaderElection is the flag to enable leader election. | ||
FlagNameLeaderElection FlagName = "leader-election" | ||
// FlagNameLeaderElectionLeaseDuration is the lease duration for the leader election. | ||
FlagNameLeaderElectionLeaseDuration FlagName = "leader-election-lease-duration" | ||
// FlagNameLeaderElectionRenewDeadline is the renew deadline for the leader election. | ||
FlagNameLeaderElectionRenewDeadline FlagName = "leader-election-renew-deadline" | ||
// FlagNameLeaderElectionRetryPeriod is the retry period for the leader election. | ||
FlagNameLeaderElectionRetryPeriod FlagName = "leader-election-retry-period" | ||
|
||
// FlagNameMetricsAddress is the address for the metrics endpoint. | ||
FlagNameMetricsAddress FlagName = "metrics-address" | ||
// FlagNameProbeAddr is the address for the health probe endpoint. | ||
FlagNameProbeAddr FlagName = "health-probe-bind-address" | ||
) | ||
|
||
// RequiredFlags contains the list of the mandatory flags. | ||
var RequiredFlags = []FlagName{ | ||
FlagNameName, | ||
FlagNameNamespace, | ||
FlagNameRemoteClusterID, | ||
FlagNameGatewayUID, | ||
FlagNameMode, | ||
} | ||
|
||
// ClientRequiredFlags contains the list of the mandatory flags for the client mode. | ||
var ClientRequiredFlags = []FlagName{ | ||
FlagNameEndpointAddress, | ||
} | ||
|
||
// InitFlags initializes the flags for the wireguard tunnel. | ||
func InitFlags(flagset *pflag.FlagSet, opts *Options) { | ||
flagset.StringVar(&opts.Name, FlagNameName.String(), "", "Parent gateway name") | ||
flagset.StringVar(&opts.Namespace, FlagNameNamespace.String(), "", "Parent gateway namespace") | ||
flagset.StringVar(&opts.RemoteClusterID, FlagNameRemoteClusterID.String(), "", "ClusterID of the remote cluster") | ||
flagset.StringVar(&opts.GatewayUID, FlagNameGatewayUID.String(), "", "Parent gateway resource UID") | ||
|
||
flagset.Var(&opts.Mode, FlagNameMode.String(), "Parent gateway mode") | ||
flagset.IntVar(&opts.MTU, FlagNameMTU.String(), 1420, "MTU for the interface") | ||
flagset.StringVar(&opts.InterfaceName, FlagNameInterfaceName.String(), "liqo-tunnel", "Name for the tunnel interface") | ||
flagset.IntVar(&opts.ListenPort, FlagNameListenPort.String(), 51820, "Listen port (server only)") | ||
flagset.StringVar(&opts.EndpointAddress, FlagNameEndpointAddress.String(), "", "Endpoint address (client only)") | ||
flagset.IntVar(&opts.EndpointPort, FlagNameEndpointPort.String(), 51820, "Endpoint port (client only)") | ||
|
||
flagset.DurationVar(&opts.DNSCheckInterval, FlagNameDNSCheckInterval.String(), 5*time.Minute, "Interval between two DNS checks") | ||
|
||
flagset.BoolVar(&opts.LeaderElection, FlagNameLeaderElection.String(), false, "Enable leader election") | ||
flagset.DurationVar(&opts.LeaderElectionLeaseDuration, FlagNameLeaderElectionLeaseDuration.String(), 15*time.Second, | ||
"LeaseDuration for the leader election") | ||
flagset.DurationVar(&opts.LeaderElectionRenewDeadline, FlagNameLeaderElectionRenewDeadline.String(), 10*time.Second, | ||
"RenewDeadline for the leader election") | ||
flagset.DurationVar(&opts.LeaderElectionRetryPeriod, FlagNameLeaderElectionRetryPeriod.String(), 2*time.Second, | ||
"RetryPeriod for the leader election") | ||
|
||
flagset.StringVar(&opts.MetricsAddress, FlagNameMetricsAddress.String(), ":8080", "Address for the metrics endpoint") | ||
flagset.StringVar(&opts.ProbeAddr, FlagNameProbeAddr.String(), ":8081", "Address for the health probe endpoint") | ||
} | ||
|
||
// MarkFlagsRequired marks the flags as required. | ||
func MarkFlagsRequired(cmd *cobra.Command, opts *Options) error { | ||
for _, flag := range RequiredFlags { | ||
if err := cmd.MarkFlagRequired(flag.String()); err != nil { | ||
return err | ||
} | ||
} | ||
if opts.Mode == common.ModeClient { | ||
for _, flag := range ClientRequiredFlags { | ||
if err := cmd.MarkFlagRequired(flag.String()); err != nil { | ||
return err | ||
} | ||
} | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
// Copyright 2019-2023 The Liqo Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package wireguard | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes" | ||
corev1 "k8s.io/api/core/v1" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
"k8s.io/apimachinery/pkg/runtime" | ||
"k8s.io/apimachinery/pkg/types" | ||
"sigs.k8s.io/controller-runtime/pkg/client" | ||
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" | ||
|
||
networkingv1alpha1 "github.com/liqotech/liqo/apis/networking/v1alpha1" | ||
"github.com/liqotech/liqo/pkg/consts" | ||
"github.com/liqotech/liqo/pkg/gateway/tunnel/common" | ||
) | ||
|
||
// SetOwnerReferenceWithMode sets the owner reference of the object according to the mode. | ||
func SetOwnerReferenceWithMode(opts *Options, obj metav1.Object, scheme *runtime.Scheme) error { | ||
meta := metav1.ObjectMeta{ | ||
Name: opts.Name, | ||
Namespace: opts.Namespace, | ||
UID: types.UID(opts.GatewayUID), | ||
} | ||
switch opts.Mode { | ||
case common.ModeServer: | ||
return controllerutil.SetOwnerReference(&networkingv1alpha1.GatewayServer{ObjectMeta: meta}, obj, scheme) | ||
case common.ModeClient: | ||
return controllerutil.SetOwnerReference(&networkingv1alpha1.GatewayClient{ObjectMeta: meta}, obj, scheme) | ||
} | ||
return fmt.Errorf("invalid mode %v", opts.Mode) | ||
} | ||
|
||
// CheckKeysSecret checks if the keys secret exists and if it contains the private and public keys. | ||
func CheckKeysSecret(ctx context.Context, cl client.Client, opts *Options) (wgtypes.Key, error) { | ||
secret := &corev1.Secret{} | ||
if err := cl.Get(ctx, types.NamespacedName{Name: GenerateResourceName(opts.Name), Namespace: opts.Namespace}, secret); err != nil { | ||
return wgtypes.Key{}, err | ||
} | ||
if secret.Data == nil { | ||
return wgtypes.Key{}, nil | ||
} | ||
if k, ok := secret.Data[consts.PrivateKeyField]; !ok || len(k) != wgtypes.KeyLen { | ||
return wgtypes.Key{}, nil | ||
} | ||
if k, ok := secret.Data[consts.PublicKeyField]; !ok || len(k) != wgtypes.KeyLen { | ||
return wgtypes.Key{}, nil | ||
} | ||
return wgtypes.Key(secret.Data[consts.PrivateKeyField]), nil | ||
} | ||
|
||
// CreateKeysSecret creates the private and public keys for the Wireguard interface and save them inside a Secret resource. | ||
func CreateKeysSecret(ctx context.Context, cl client.Client, opts *Options, pri, pub wgtypes.Key) error { | ||
secret := &corev1.Secret{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: GenerateResourceName(opts.Name), | ||
Namespace: opts.Namespace, | ||
}, | ||
} | ||
|
||
if _, err := controllerutil.CreateOrUpdate(ctx, cl, secret, func() error { | ||
secret.SetLabels(map[string]string{ | ||
string(consts.RemoteClusterID): opts.RemoteClusterID, | ||
string(consts.GatewayResourceLabel): string(consts.GatewayResourceLabelValue), | ||
}) | ||
if err := SetOwnerReferenceWithMode(opts, secret, cl.Scheme()); err != nil { | ||
return err | ||
} | ||
secret.Data = map[string][]byte{ | ||
consts.PrivateKeyField: pri[:], | ||
consts.PublicKeyField: pub[:], | ||
} | ||
return nil | ||
}); err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// EnsureConnection creates or updates the connection resource. | ||
func EnsureConnection(ctx context.Context, cl client.Client, scheme *runtime.Scheme, opts *Options) error { | ||
conn := &networkingv1alpha1.Connection{ObjectMeta: metav1.ObjectMeta{ | ||
Name: GenerateResourceName(opts.Name), Namespace: opts.Namespace, | ||
}} | ||
_, err := controllerutil.CreateOrUpdate(ctx, cl, conn, func() error { | ||
if err := SetOwnerReferenceWithMode(opts, conn, scheme); err != nil { | ||
return err | ||
} | ||
conn.Spec.GatewayRef.APIVersion = networkingv1alpha1.GroupVersion.String() | ||
conn.Spec.GatewayRef.Name = opts.Name | ||
conn.Spec.GatewayRef.Namespace = opts.Namespace | ||
conn.Spec.GatewayRef.UID = types.UID(opts.GatewayUID) | ||
switch opts.Mode { | ||
case common.ModeServer: | ||
conn.Spec.Type = networkingv1alpha1.ConnectionTypeServer | ||
conn.Spec.GatewayRef.Kind = networkingv1alpha1.WgGatewayServerKind | ||
case common.ModeClient: | ||
conn.Spec.Type = networkingv1alpha1.ConnectionTypeClient | ||
conn.Spec.GatewayRef.Kind = networkingv1alpha1.WgGatewayClientKind | ||
} | ||
return nil | ||
}) | ||
|
||
return err | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
// Copyright 2019-2023 The Liqo Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package wireguard | ||
|
||
import ( | ||
"context" | ||
|
||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes" | ||
kerrors "k8s.io/apimachinery/pkg/api/errors" | ||
"sigs.k8s.io/controller-runtime/pkg/client" | ||
) | ||
|
||
// cluster-role | ||
// +kubebuilder:rbac:groups=core,resources=secrets,verbs=get;list;create;delete;update | ||
|
||
// EnsureKeysSecret ensure the presence of the private and public keys for the Wireguard interface and save them inside a Secret resource and Options. | ||
func EnsureKeysSecret(ctx context.Context, cl client.Client, opts *Options) error { | ||
var pri, pub wgtypes.Key | ||
var err error | ||
pri, err = CheckKeysSecret(ctx, cl, opts) | ||
|
||
switch { | ||
case kerrors.IsNotFound(err) || len(pri) == 0: | ||
pri, err = wgtypes.GeneratePrivateKey() | ||
if err != nil { | ||
return err | ||
} | ||
pub = pri.PublicKey() | ||
if err := CreateKeysSecret(ctx, cl, opts, pri, pub); err != nil { | ||
return err | ||
} | ||
case err != nil: | ||
return err | ||
} | ||
|
||
opts.PrivateKey = pri | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
// Copyright 2019-2023 The Liqo Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package wireguard | ||
|
||
import "github.com/liqotech/liqo/pkg/gateway/tunnel/common" | ||
|
||
// Labels is the type used to identify the wireguard labels. | ||
type Labels string | ||
|
||
// LabelsValue is the type used to identify the wireguard labels values. | ||
type LabelsValue string | ||
|
||
const ( | ||
// LabelsMode is the label used to identify the wireguard mode. | ||
LabelsMode Labels = "networking.liqo.io/wireguard-mode" | ||
) | ||
|
||
const ( | ||
// LabelsModeServer is the label used to identify the wireguard mode server. | ||
LabelsModeServer LabelsValue = LabelsValue(common.ModeServer) | ||
// LabelsModeClient is the label used to identify the wireguard mode client. | ||
LabelsModeClient LabelsValue = LabelsValue(common.ModeClient) | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
// Copyright 2019-2023 The Liqo Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package wireguard | ||
|
||
import ( | ||
"github.com/vishvananda/netlink" | ||
"golang.zx2c4.com/wireguard/wgctrl" | ||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes" | ||
"k8s.io/klog/v2" | ||
|
||
"github.com/liqotech/liqo/pkg/gateway/tunnel/common" | ||
) | ||
|
||
const ( | ||
// ServerInterfaceIP is the IP address of the Wireguard interface in server mode. | ||
ServerInterfaceIP = "169.254.0.1/30" | ||
// ClientInterfaceIP is the IP address of the Wireguard interface in client mode. | ||
ClientInterfaceIP = "169.254.0.2/30" | ||
) | ||
|
||
// InitWireguardLink inits the Wireguard interface. | ||
func InitWireguardLink(options *Options) error { | ||
if err := createLink(options); err != nil { | ||
return err | ||
} | ||
|
||
link, err := common.GetLink(options.InterfaceName) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
klog.Infof("Setting up Wireguard interface %q with IP %q", options.InterfaceName, GetInterfaceIP(options.Mode)) | ||
if err := common.AddAddress(link, GetInterfaceIP(options.Mode)); err != nil { | ||
return err | ||
} | ||
|
||
return netlink.LinkSetUp(link) | ||
} | ||
|
||
// GetInterfaceIP returns the IP address of the Wireguard interface. | ||
func GetInterfaceIP(mode common.Mode) string { | ||
switch mode { | ||
case common.ModeServer: | ||
return ServerInterfaceIP | ||
case common.ModeClient: | ||
return ClientInterfaceIP | ||
} | ||
return "" | ||
} | ||
|
||
// CreateLink creates a new Wireguard interface. | ||
func createLink(options *Options) error { | ||
link := netlink.Wireguard{ | ||
LinkAttrs: netlink.LinkAttrs{ | ||
MTU: options.MTU, | ||
Name: options.InterfaceName, | ||
}, | ||
} | ||
|
||
err := netlink.LinkAdd(&link) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if options.Mode == common.ModeServer { | ||
wgcl, err := wgctrl.New() | ||
if err != nil { | ||
return err | ||
} | ||
defer wgcl.Close() | ||
|
||
if err := wgcl.ConfigureDevice(options.InterfaceName, wgtypes.Config{ | ||
ListenPort: &options.ListenPort, | ||
}); err != nil { | ||
return err | ||
} | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
// Copyright 2019-2023 The Liqo Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package wireguard | ||
|
||
import ( | ||
"net" | ||
"sync" | ||
"time" | ||
|
||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes" | ||
|
||
"github.com/liqotech/liqo/pkg/gateway/tunnel/common" | ||
) | ||
|
||
// Options contains the options for the wireguard interface. | ||
type Options struct { | ||
Name string | ||
Namespace string | ||
RemoteClusterID string | ||
GatewayUID string | ||
|
||
Mode common.Mode | ||
MTU int | ||
PrivateKey wgtypes.Key | ||
InterfaceName string | ||
InterfaceIP string | ||
ListenPort int | ||
EndpointAddress string | ||
EndpointPort int | ||
|
||
EndpointIP net.IP | ||
EndpointIPMutex *sync.Mutex | ||
|
||
DNSCheckInterval time.Duration | ||
|
||
LeaderElection bool | ||
LeaderElectionLeaseDuration time.Duration | ||
LeaderElectionRenewDeadline time.Duration | ||
LeaderElectionRetryPeriod time.Duration | ||
|
||
MetricsAddress string | ||
ProbeAddr string | ||
} | ||
|
||
// NewOptions returns a new Options struct. | ||
func NewOptions() *Options { | ||
return &Options{ | ||
EndpointIPMutex: &sync.Mutex{}, | ||
} | ||
} | ||
|
||
// GenerateResourceName generates the name used for the resources created by the gateway. | ||
// This will help if a suffix will be added to the name of the resources in future. | ||
func GenerateResourceName(name string) string { | ||
return name | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
// Copyright 2019-2023 The Liqo Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package wireguard | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
"golang.zx2c4.com/wireguard/wgctrl" | ||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes" | ||
apierrors "k8s.io/apimachinery/pkg/api/errors" | ||
"k8s.io/apimachinery/pkg/runtime" | ||
"k8s.io/client-go/tools/record" | ||
"k8s.io/klog/v2" | ||
ctrl "sigs.k8s.io/controller-runtime" | ||
"sigs.k8s.io/controller-runtime/pkg/builder" | ||
"sigs.k8s.io/controller-runtime/pkg/client" | ||
"sigs.k8s.io/controller-runtime/pkg/event" | ||
"sigs.k8s.io/controller-runtime/pkg/predicate" | ||
|
||
networkingv1alpha1 "github.com/liqotech/liqo/apis/networking/v1alpha1" | ||
"github.com/liqotech/liqo/pkg/consts" | ||
) | ||
|
||
// cluster-role | ||
// +kubebuilder:rbac:groups=networking.liqo.io,resources=publickeys,verbs=get;list;create;delete;update | ||
|
||
// PublicKeysReconciler updates the PublicKey resource used to establish the Wireguard connection. | ||
type PublicKeysReconciler struct { | ||
Wgcl *wgctrl.Client | ||
Client client.Client | ||
Scheme *runtime.Scheme | ||
EventsRecorder record.EventRecorder | ||
Options *Options | ||
} | ||
|
||
// NewPublicKeysReconciler returns a new PublicKeysReconciler. | ||
func NewPublicKeysReconciler(cl client.Client, s *runtime.Scheme, er record.EventRecorder, options *Options) (*PublicKeysReconciler, error) { | ||
wgcl, err := wgctrl.New() | ||
if err != nil { | ||
return nil, fmt.Errorf("unable to create wireguard client: %w", err) | ||
} | ||
return &PublicKeysReconciler{ | ||
Wgcl: wgcl, | ||
Client: cl, | ||
Scheme: s, | ||
EventsRecorder: er, | ||
Options: options, | ||
}, nil | ||
} | ||
|
||
// Reconcile manage PublicKey resources. | ||
func (r *PublicKeysReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { | ||
publicKey := &networkingv1alpha1.PublicKey{} | ||
if err := r.Client.Get(ctx, req.NamespacedName, publicKey); err != nil { | ||
if apierrors.IsNotFound(err) { | ||
klog.Infof("There is no publicKey %s", req.String()) | ||
return ctrl.Result{}, nil | ||
} | ||
return ctrl.Result{}, fmt.Errorf("unable to get the publicKey %q: %w", req.NamespacedName, err) | ||
} | ||
|
||
if err := configureDevice(r.Wgcl, r.Options, wgtypes.Key(publicKey.Spec.PublicKey)); err != nil { | ||
return ctrl.Result{}, err | ||
} | ||
|
||
return ctrl.Result{}, EnsureConnection(ctx, r.Client, r.Scheme, r.Options) | ||
} | ||
|
||
// SetupWithManager register the ConfigurationReconciler to the manager. | ||
func (r *PublicKeysReconciler) SetupWithManager(mgr ctrl.Manager, src <-chan event.GenericEvent) error { | ||
return ctrl.NewControllerManagedBy(mgr). | ||
For(&networkingv1alpha1.PublicKey{}, r.Predicates()). | ||
WatchesRawSource(NewDNSSource(src), NewDNSEventHandler(r.Client, r.Options)). | ||
Complete(r) | ||
} | ||
|
||
// Predicates returns the predicates required for the PublicKey controller. | ||
func (r *PublicKeysReconciler) Predicates() builder.Predicates { | ||
return builder.WithPredicates( | ||
predicate.NewPredicateFuncs(func(object client.Object) bool { | ||
mode, ok := object.GetLabels()[string(LabelsMode)] | ||
if !ok { | ||
return false | ||
} | ||
if mode != string(r.Options.Mode) { | ||
return false | ||
} | ||
id, ok := object.GetLabels()[string(consts.RemoteClusterID)] | ||
if !ok { | ||
return false | ||
} | ||
return id == r.Options.RemoteClusterID | ||
})) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// Copyright 2019-2023 The Liqo Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
// Package flags provides a set of utilities to manage flags. | ||
package flags |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
// Copyright 2019-2023 The Liqo Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package flags | ||
|
||
import ( | ||
"flag" | ||
|
||
"github.com/spf13/pflag" | ||
) | ||
|
||
// FromFlagToPflag copies the flags from a flag.FlagSet to a pflag.FlagSet. | ||
func FromFlagToPflag(flags *flag.FlagSet, pflags *pflag.FlagSet) { | ||
flags.VisitAll(func(f *flag.Flag) { | ||
pflags.AddGoFlag(f) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters