*: add peer VPN support
This commit adds support for defining arbitrary peers that should have access to the VPN. In k8s, this is accomplished using the new Peer CRD.
This commit is contained in:
20
pkg/k8s/apis/kilo/register.go
Normal file
20
pkg/k8s/apis/kilo/register.go
Normal file
@@ -0,0 +1,20 @@
|
||||
// Copyright 2019 the Kilo 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 kilo
|
||||
|
||||
const (
|
||||
// GroupName contains the API group name for Kilo API group.
|
||||
GroupName = "kilo"
|
||||
)
|
19
pkg/k8s/apis/kilo/v1alpha1/doc.go
Normal file
19
pkg/k8s/apis/kilo/v1alpha1/doc.go
Normal file
@@ -0,0 +1,19 @@
|
||||
// Copyright 2019 the Kilo 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.
|
||||
|
||||
// +k8s:deepcopy-gen=package,register
|
||||
|
||||
// Package v1alpha1 is the v1alpha1 version of the API.
|
||||
// +groupName=kilo
|
||||
package v1alpha1
|
12127
pkg/k8s/apis/kilo/v1alpha1/openapi_generated.go
Normal file
12127
pkg/k8s/apis/kilo/v1alpha1/openapi_generated.go
Normal file
File diff suppressed because it is too large
Load Diff
49
pkg/k8s/apis/kilo/v1alpha1/register.go
Normal file
49
pkg/k8s/apis/kilo/v1alpha1/register.go
Normal file
@@ -0,0 +1,49 @@
|
||||
// Copyright 2019 the Kilo 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 v1alpha1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
var (
|
||||
// SchemeBuilder exposes an API scheme builder for this API version.
|
||||
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
|
||||
// AddToScheme exposes an AddToScheme func for this API version.
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
// GroupName is the group name used in this package.
|
||||
const GroupName = "kilo.squat.ai"
|
||||
|
||||
// SchemeGroupVersion is the group version used to register these objects.
|
||||
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"}
|
||||
|
||||
// Resource takes an unqualified resource and returns a Group-qualified GroupResource.
|
||||
func Resource(resource string) schema.GroupResource {
|
||||
return SchemeGroupVersion.WithResource(resource).GroupResource()
|
||||
}
|
||||
|
||||
// addKnownTypes adds the set of types defined in this package to the supplied scheme.
|
||||
func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&Peer{},
|
||||
&PeerList{},
|
||||
)
|
||||
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
|
||||
return nil
|
||||
}
|
143
pkg/k8s/apis/kilo/v1alpha1/types.go
Normal file
143
pkg/k8s/apis/kilo/v1alpha1/types.go
Normal file
@@ -0,0 +1,143 @@
|
||||
// Copyright 2019 the Kilo 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 v1alpha1
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
const (
|
||||
// PeerKind is the API kind for the peer resource.
|
||||
PeerKind = "Peer"
|
||||
// PeerPlural is the plural name for the peer resource.
|
||||
PeerPlural = "peers"
|
||||
)
|
||||
|
||||
// PeerShortNames are convenient shortnames for the peer resource.
|
||||
var PeerShortNames = []string{"peer"}
|
||||
|
||||
// +genclient
|
||||
// +genclient:nonNamespaced
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
// +k8s:openapi-gen=true
|
||||
|
||||
// Peer is a WireGuard peer that should have access to the VPN.
|
||||
type Peer struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
// Standard object’s metadata. More info:
|
||||
// https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#metadata
|
||||
// +k8s:openapi-gen=false
|
||||
metav1.ObjectMeta `json:"metadata"`
|
||||
// Specification of the desired behavior of the Kilo Peer. More info:
|
||||
// https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status
|
||||
Spec PeerSpec `json:"spec"`
|
||||
}
|
||||
|
||||
// PeerSpec is the description and configuration of a peer.
|
||||
// +k8s:openapi-gen=true
|
||||
type PeerSpec struct {
|
||||
// AllowedIPs is the list of IP addresses that are allowed
|
||||
// for the given peer's tunnel.
|
||||
AllowedIPs []string `json:"allowedIPs"`
|
||||
// Endpoint is the initial endpoint for connections to the peer.
|
||||
// +optional
|
||||
Endpoint *PeerEndpoint `json:"endpoint"`
|
||||
// PersistentKeepalive is the interval in seconds of the emission
|
||||
// of keepalive packets to the peer. This defaults to 0, which
|
||||
// disables the feature.
|
||||
PersistentKeepalive int `json:"persistentKeepalive"`
|
||||
// PublicKey is the WireGuard public key for the node.
|
||||
PublicKey string `json:"publicKey"`
|
||||
}
|
||||
|
||||
// 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"`
|
||||
// Port must be a valid port number.
|
||||
Port uint32 `json:"port"`
|
||||
}
|
||||
|
||||
// PeerName is the peer resource's FQDN.
|
||||
var PeerName = PeerPlural + "." + GroupName
|
||||
|
||||
// AsOwner creates a new owner reference for the peer to apply to dependent resource.
|
||||
func (p *Peer) AsOwner() metav1.OwnerReference {
|
||||
trueVar := true
|
||||
return metav1.OwnerReference{
|
||||
APIVersion: p.APIVersion,
|
||||
Kind: p.Kind,
|
||||
Name: p.Name,
|
||||
UID: p.UID,
|
||||
BlockOwnerDeletion: &trueVar,
|
||||
Controller: &trueVar,
|
||||
}
|
||||
}
|
||||
|
||||
// Copy creates a deep copy of the peer.
|
||||
func (p *Peer) Copy() *Peer {
|
||||
new := Peer{}
|
||||
b, err := json.Marshal(*p)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = json.Unmarshal(b, &new)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return &new
|
||||
}
|
||||
|
||||
// Validate ensures that all the fields of a peer's spec are valid.
|
||||
func (p *Peer) Validate() error {
|
||||
for _, ip := range p.Spec.AllowedIPs {
|
||||
if _, n, err := net.ParseCIDR(ip); err != nil {
|
||||
return fmt.Errorf("failed to parse %q as a valid IP address: %v", ip, err)
|
||||
} else if n == nil {
|
||||
return fmt.Errorf("got invalid IP address for %q", ip)
|
||||
}
|
||||
}
|
||||
if p.Spec.Endpoint != nil {
|
||||
if 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 {
|
||||
return fmt.Errorf("port must be a valid UDP port number, got %d", p.Spec.Endpoint.Port)
|
||||
}
|
||||
}
|
||||
if p.Spec.PersistentKeepalive < 0 {
|
||||
return fmt.Errorf("persistent keepalive must be greater than or equal to zero; got %q", p.Spec.PersistentKeepalive)
|
||||
}
|
||||
if len(p.Spec.PublicKey) == 0 {
|
||||
return errors.New("public keys cannot be empty")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// PeerList is a list of peers.
|
||||
type PeerList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata"`
|
||||
// List of peers.
|
||||
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md
|
||||
Items []Peer `json:"items"`
|
||||
}
|
125
pkg/k8s/apis/kilo/v1alpha1/zz_generated.deepcopy.go
Normal file
125
pkg/k8s/apis/kilo/v1alpha1/zz_generated.deepcopy.go
Normal file
@@ -0,0 +1,125 @@
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
// Copyright 2019 the Kilo 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.
|
||||
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
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 *Peer) DeepCopyInto(out *Peer) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Peer.
|
||||
func (in *Peer) DeepCopy() *Peer {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Peer)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *Peer) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 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
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PeerEndpoint.
|
||||
func (in *PeerEndpoint) DeepCopy() *PeerEndpoint {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PeerEndpoint)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PeerList) DeepCopyInto(out *PeerList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
out.ListMeta = in.ListMeta
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]Peer, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PeerList.
|
||||
func (in *PeerList) DeepCopy() *PeerList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PeerList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *PeerList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PeerSpec) DeepCopyInto(out *PeerSpec) {
|
||||
*out = *in
|
||||
if in.AllowedIPs != nil {
|
||||
in, out := &in.AllowedIPs, &out.AllowedIPs
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Endpoint != nil {
|
||||
in, out := &in.Endpoint, &out.Endpoint
|
||||
*out = new(PeerEndpoint)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PeerSpec.
|
||||
func (in *PeerSpec) DeepCopy() *PeerSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PeerSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
Reference in New Issue
Block a user