Skip to content

Commit

Permalink
Added Main
Browse files Browse the repository at this point in the history
  • Loading branch information
cheina97 committed Oct 2, 2023
1 parent c3a0621 commit 1b0c59b
Show file tree
Hide file tree
Showing 6 changed files with 219 additions and 30 deletions.
83 changes: 76 additions & 7 deletions cmd/gateway/tunnel/wireguard/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,38 +19,106 @@ import (
"fmt"
"os"

"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/log"

ipamv1alpha1 "github.com/liqotech/liqo/apis/ipam/v1alpha1"
networkingv1alpha1 "github.com/liqotech/liqo/apis/networking/v1alpha1"
"github.com/liqotech/liqo/pkg/gateway/tunnel/wireguard"
"github.com/liqotech/liqo/pkg/utils/mapper"
"github.com/liqotech/liqo/pkg/utils/restcfg"
)

// cluster-role
// +kubebuilder:rbac:groups=core,resources=secrets,verbs=get;list;create;delete;update
// +kubebuilder:rbac:groups=networking.liqo.io,resources=publickeys,verbs=get;list;create;delete;update

var (
addToSchemeFunctions = []func(*runtime.Scheme) error{
networkingv1alpha1.AddToScheme,
ipamv1alpha1.AddToScheme,
}
)

func main() {
klog.Infof("Starting wg-liqo")
var err error
ctx := ctrl.SetupSignalHandler()
options := wireguard.Options{}
scheme := runtime.NewScheme()

// Init flags and check mandatory ones.
restcfg.InitFlags(nil)
klog.InitFlags(nil)
wireguard.InitFlags(&options)
flag.Parse()

if options.Mode == "" {
klog.Errorf("mode cannot be empty")
if err = wireguard.CheckMandatoryFlags(wireguard.MandatoryFlags); err != nil {
klog.Errorf("Mandatory flags: %v", err)
os.Exit(1)
}

klog.Infof("Options: %v", options)
// Adds the APIs to the scheme.
for _, addToScheme := range addToSchemeFunctions {
if err = addToScheme(scheme); err != nil {
klog.Errorf("unable to add scheme: %v", err)
os.Exit(1)
}
}

// Set controller-runtime logger.
log.SetLogger(klog.NewKlogr())

// Init a controller-runtime client to interact with the cluster.
cfg := config.GetConfigOrDie()
_, err := client.New(cfg, client.Options{})

_, err = client.New(cfg, client.Options{})
if err != nil {
klog.Errorf("unable to create client: %v", err)
os.Exit(1)
}

// Create the manager.
mgr, err := ctrl.NewManager(cfg, ctrl.Options{
MapperProvider: mapper.LiqoMapperProvider(scheme),
Scheme: scheme,
MetricsBindAddress: options.MetricsAddress,
HealthProbeBindAddress: options.ProbeAddr,
LeaderElection: options.LeaderElection,
LeaderElectionID: "66cf253f.wgtunnel.liqo.io",
LeaderElectionNamespace: options.Namespace,
LeaderElectionReleaseOnCancel: true,
LeaderElectionResourceLock: resourcelock.LeasesResourceLock,
})
if err != nil {
klog.Error(err)
os.Exit(1)
}

// Setup the controller.
pkr, err := wireguard.NewPublicKeysReconciler(
mgr.GetClient(),
mgr.GetScheme(),
mgr.GetEventRecorderFor("wireguard-controller"),
)
if err != nil {
klog.Error(err)
os.Exit(1)
}

// Setup the controller.
if err = pkr.SetupWithManager(mgr); err != nil {
klog.Error(err)
os.Exit(1)
}

if err = mgr.Start(ctx); err != nil {
klog.Error(err)
os.Exit(1)
}

// Create the wg-liqo interface.
err = wireguard.CreateLink(&options)
if err != nil {
Expand All @@ -67,4 +135,5 @@ func main() {

fmt.Print(link)
klog.Infof("wg-liqo interface created successfully")

Check failure on line 138 in cmd/gateway/tunnel/wireguard/main.go

View workflow job for this annotation

GitHub Actions / Lint golang files

unnecessary trailing newline (whitespace)
}
59 changes: 57 additions & 2 deletions pkg/gateway/tunnel/wireguard/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,65 @@ package wireguard

import (
"flag"
"fmt"
)

type FlagName string

Check warning on line 22 in pkg/gateway/tunnel/wireguard/flags.go

View workflow job for this annotation

GitHub Actions / Lint golang files

exported: exported type FlagName should have comment or be unexported (revive)

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"

// 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"
// FlagNameMetricsAddress is the address for the metrics endpoint.
FlagNameMetricsAddress FlagName = "metrics-address"

// FlagNameLeaderElection is the flag to enable leader election.
FlagNameLeaderElection FlagName = "leader-election"
// FlagNameProbeAddr is the address for the health probe endpoint.
FlagNameProbeAddr FlagName = "health-probe-bind-address"
)

// MandatoryFlags contains the list of the mandatory flags.
var MandatoryFlags = []FlagName{
FlagNameName,
FlagNameNamespace,
FlagNameMode,
}

// InitFlags initializes the flags for the wireguard tunnel.
func InitFlags(options *Options) {
flag.Var(&options.Mode, "mode", "Mode for the wireguard interface")
flag.IntVar(&options.MTU, "mtu", 1420, "MTU for the wireguard interface")
flag.StringVar(&options.Name, FlagNameName.String(), "", "Name for the wireguard interface")
flag.StringVar(&options.Namespace, FlagNameNamespace.String(), "", "Namespace for the wireguard interface")

flag.Var(&options.Mode, FlagNameMode.String(), "Mode for the wireguard interface")
flag.IntVar(&options.MTU, FlagNameMTU.String(), 1420, "MTU for the wireguard interface")

flag.StringVar(&options.MetricsAddress, FlagNameMetricsAddress.String(), ":8080", "Address for the metrics endpoint")
flag.BoolVar(&options.LeaderElection, FlagNameLeaderElection.String(), false, "Enable leader election")
flag.StringVar(&options.ProbeAddr, FlagNameProbeAddr.String(), ":8081", "Address for the health probe endpoint")
}

// CheckMandatoryFlags checks if the mandatory flags are set.
// This function must be called after flag.Parse().
func CheckMandatoryFlags(flags []FlagName) error {
for _, fn := range flags {
f := flag.Lookup(fn.String())
if f == nil {
return fmt.Errorf("flag %s not found", fn)
}
if f.Value.String() == "" {
return fmt.Errorf("flag %s cannot be empty", fn)
}
}
return nil
}
14 changes: 14 additions & 0 deletions pkg/gateway/tunnel/wireguard/labels.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
// 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

type WireguardLabels string

Check warning on line 17 in pkg/gateway/tunnel/wireguard/labels.go

View workflow job for this annotation

GitHub Actions / Lint golang files

exported: exported type WireguardLabels should have comment or be unexported (revive)
Expand Down
19 changes: 16 additions & 3 deletions pkg/gateway/tunnel/wireguard/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@

package wireguard

import "fmt"
import (
"fmt"

"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
)

// Mode is the mode in which the wireguard interface is configured.
type Mode string
Expand Down Expand Up @@ -45,6 +49,15 @@ func (m *Mode) Set(value string) error {

// Options contains the options for the wireguard interface.
type Options struct {
Mode Mode
MTU int
Name string
Namespace string

Mode Mode
MTU int
PrivateKey wgtypes.Key
PublicKey wgtypes.Key

LeaderElection bool
MetricsAddress string
ProbeAddr string
}
44 changes: 33 additions & 11 deletions pkg/gateway/tunnel/wireguard/tunnel-controller.go
Original file line number Diff line number Diff line change
@@ -1,51 +1,73 @@
// 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"
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/client"

ipamv1alpha1 "github.com/liqotech/liqo/apis/ipam/v1alpha1"
networkingv1alpha1 "github.com/liqotech/liqo/apis/networking/v1alpha1"
)

type WireguardController struct {
client.Client
// PublicKeysReconciler updates the PublicKey resource used to establish the Wireguard connection.
type PublicKeysReconciler struct {
Wgctrl *wgctrl.Client
Client client.Client
Scheme *runtime.Scheme
EventsRecorder record.EventRecorder
}

func NewWireguardController(cl client.Client, s *runtime.Scheme, er record.EventRecorder) *WireguardController {
return &WireguardController{
// NewPublicKeysReconciler returns a new PublicKeysReconciler.
func NewPublicKeysReconciler(cl client.Client, s *runtime.Scheme, er record.EventRecorder) (*PublicKeysReconciler, error) {
wgctrl, err := wgctrl.New()

Check failure on line 42 in pkg/gateway/tunnel/wireguard/tunnel-controller.go

View workflow job for this annotation

GitHub Actions / Lint golang files

importShadow: shadow of imported from 'golang.zx2c4.com/wireguard/wgctrl' package 'wgctrl' (gocritic)
if err != nil {
return nil, fmt.Errorf("unable to create wireguard client: %w", err)
}
return &PublicKeysReconciler{
Wgctrl: wgctrl,
Client: cl,
Scheme: s,
EventsRecorder: er,
}
}, nil
}

// Reconcile manage PublicKey resources.
func (r *WireguardController) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
func (r *PublicKeysReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
publicKey := &networkingv1alpha1.PublicKey{}
if err := r.Get(ctx, req.NamespacedName, publicKey); err != nil {
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)
}

return ctrl.Result{}, nil
}

// SetupWithManager register the ConfigurationReconciler to the manager.
func (r *WireguardController) SetupWithManager(mgr ctrl.Manager) error {
func (r *PublicKeysReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
For(&networkingv1alpha1.Configuration{}).
Owns(&ipamv1alpha1.Network{}).
For(&networkingv1alpha1.PublicKey{}).
Complete(r)
}
30 changes: 23 additions & 7 deletions pkg/gateway/tunnel/wireguard/wireguard.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"golang.zx2c4.com/wireguard/wgctrl"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/klog/v2"
"sigs.k8s.io/controller-runtime/pkg/client"
ctrlutil "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
Expand All @@ -28,6 +29,11 @@ import (
const (
// WireguardInterfaceName is the name of the wireguard interface.
WireguardInterfaceName = "liqo-wg"

// SecretPrivateKeyField is the name of the field inside the Secret resource that contains the private key.
SecretPrivateKeyField = "private-key"
// SecretPublicKeyField is the name of the field inside the Secret resource that contains the public key.
SecretPublicKeyField = "public-key"
)

var wgcl *wgctrl.Client

Check failure on line 39 in pkg/gateway/tunnel/wireguard/wireguard.go

View workflow job for this annotation

GitHub Actions / Lint golang files

var `wgcl` is unused (unused)
Expand All @@ -40,21 +46,31 @@ func init() {
}
}

// CreateKeys creates the private and public keys for the Wireguard interface and save it inside a Secret resource.
// CreateKeys creates the private and public keys for the Wireguard interface and save them inside a Secret resource and Options.
func CreateKeys(ctx context.Context, cl client.Client, opts *Options) error {
pri, err := wgtypes.GeneratePrivateKey()
if err != nil {
return err
}
pri.PublicKey()
pub := pri.PublicKey()

opts.PrivateKey = pri
opts.PublicKey = pub

secret := &corev1.Secret{
ObjectMeta: ctrlutil.ObjectMeta{
ObjectMeta: metav1.ObjectMeta{
Name: opts.Name,
Namespace: opts.Namespace,
},
}
ctrlutil.CreateOrUpdate(ctx, cl, secret, func() error {

})

if _, err = ctrlutil.CreateOrUpdate(ctx, cl, secret, func() error {
secret.Data = map[string][]byte{
SecretPrivateKeyField: opts.PrivateKey[:],
SecretPublicKeyField: opts.PublicKey[:],
}
return nil
}); err != nil {
return err
}
return nil
}

0 comments on commit 1b0c59b

Please sign in to comment.