pkg/k8s: enable peers to use DNS names

This commit enables peers defined using the Peer CRD to declare their
endpoints using DNS names.

Signed-off-by: Lucas Servén Marín <lserven@gmail.com>
This commit is contained in:
Lucas Servén Marín
2020-02-28 15:48:32 +01:00
parent e3cb7d7958
commit 116fb7337a
6 changed files with 102 additions and 15 deletions

View File

@@ -19,9 +19,11 @@ import (
"errors"
"fmt"
"net"
"strings"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/validation"
)
const (
@@ -81,12 +83,22 @@ type PeerSpec struct {
// PeerEndpoint represents a WireGuard enpoint, which is a ip:port tuple.
type PeerEndpoint struct {
// IP must be a valid IP address.
IP string `json:"ip"`
DNSOrIP
// Port must be a valid port number.
Port uint32 `json:"port"`
}
// DNSOrIP represents either a DNS name or an IP address.
// IPs, as they are more specific, are preferred.
type DNSOrIP struct {
// DNS must be a valid RFC 1123 subdomain.
// +optional
DNS string `json:"dns,omitempty"`
// IP must be a valid IP address.
// +optional
IP string `json:"ip,omitempty"`
}
// PeerName is the peer resource's FQDN.
var PeerName = PeerPlural + "." + GroupName
@@ -127,10 +139,18 @@ func (p *Peer) Validate() error {
}
}
if p.Spec.Endpoint != nil {
if net.ParseIP(p.Spec.Endpoint.IP) == nil {
if p.Spec.Endpoint.IP == "" && p.Spec.Endpoint.DNS == "" {
return errors.New("either an endpoint DNS name IP address must be given")
}
if p.Spec.Endpoint.DNS != "" {
if errs := validation.IsDNS1123Subdomain(p.Spec.Endpoint.DNS); len(errs) != 0 {
return errors.New(strings.Join(errs, "; "))
}
}
if p.Spec.Endpoint.IP != "" && net.ParseIP(p.Spec.Endpoint.IP) == nil {
return fmt.Errorf("failed to parse %q as a valid IP address", p.Spec.Endpoint.IP)
}
if p.Spec.Endpoint.Port == 0 {
if 1 > p.Spec.Endpoint.Port || p.Spec.Endpoint.Port > 65535 {
return fmt.Errorf("port must be a valid UDP port number, got %d", p.Spec.Endpoint.Port)
}
}

View File

@@ -22,6 +22,22 @@ import (
runtime "k8s.io/apimachinery/pkg/runtime"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *DNSOrIP) DeepCopyInto(out *DNSOrIP) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DNSOrIP.
func (in *DNSOrIP) DeepCopy() *DNSOrIP {
if in == nil {
return nil
}
out := new(DNSOrIP)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Peer) DeepCopyInto(out *Peer) {
*out = *in
@@ -52,6 +68,7 @@ func (in *Peer) DeepCopyObject() runtime.Object {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *PeerEndpoint) DeepCopyInto(out *PeerEndpoint) {
*out = *in
out.DNSOrIP = in.DNSOrIP
return
}