Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions config/crd/bases/skupper_link_crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,14 @@ spec:
description: |-
The configured routing cost of sending traffic over the link.
type: integer
routingKeys:
type: array
description: |-
Optional. A list of routing key identifiers available in the local VAN
that are accessible to the remote network over this link.
This is only used in inter-network connections (multi-van).
items:
type: string
settings:
description: |-
A map containing additional settings. Each map entry has a
Expand Down
33 changes: 30 additions & 3 deletions config/crd/bases/skupper_router_access_crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,27 @@ spec:
roles:
description: |-
The named interfaces by which a router can be accessed. These
include "inter-router" for links between interior routers and
"edge" for links from edge routers to interior routers.
include "inter-router" for links between interior routers,
"edge" for links from edge routers to interior routers,
"inter-network" for multi-van links.
type: array
maxItems: 4
items:
type: object
properties:
name:
description: The role name. Either "inter-router" or "edge".
description: The role name. One of "inter-router", "edge" or "inter-network".
type: string
port:
description: The port for the router to bind. Must not conflict with another role.
type: integer
required:
- name
x-kubernetes-validations:
- rule: "self.all(r, self.filter(x, x.name == r.name).size() == 1)"
message: "spec.roles must not contain duplicate role names"
- rule: "self.filter(x, has(x.port) && x.port > 0).all(r, self.filter(x, has(x.port) && x.port == r.port).size() == 1)"
message: "spec.roles must not contain duplicate non-zero ports"
generateTlsCredentials:
description: |-
When set, Skupper generates the TLS credentials to be
Expand Down Expand Up @@ -89,6 +96,14 @@ spec:
The hostnames and IPs secured by the router TLS certificate.
items:
type: string
routingKeys:
type: array
description: |-
Optional. A list of routing key identifiers available in the local VAN
that are accessible to the remote network over this ingress.
This is only used in inter-network connections (multi-van).
items:
type: string
Comment thread
coderabbitai[bot] marked this conversation as resolved.
settings:
description: |-
Advanced. A map containing additional settings. Each map
Expand Down Expand Up @@ -162,6 +177,18 @@ spec:
- reason
- status
- type
roles:
type: array
description: |-
List of roles and their allocated ports.
If a role does not specify a port, the controller assigns a dynamic port and reports it here.
items:
type: object
properties:
name:
type: string
port:
type: integer
endpoints:
type: array
description: |-
Expand Down
7 changes: 7 additions & 0 deletions config/crd/bases/skupper_site_crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,13 @@ spec:
there is little benefit.

Currently, edge sites cannot also have HA enabled.
networkId:
type: string
description: |-
Optional. An identifier for the network this site belongs to.
When set, the router uses this value to advertise inter-network
topology addresses, enabling multi-VAN connectivity. All sites
connected to this VAN must use the same network identifier.
settings:
description: |-
Advanced. A map containing additional settings. Each map
Expand Down
6 changes: 6 additions & 0 deletions config/rbac/cluster/clusterrole.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,12 @@ rules:
- create
- delete
- update
- apiGroups:
- apiextensions.k8s.io
resources:
- customresourcedefinitions
verbs:
- get
- apiGroups:
- skupper.io
resources:
Expand Down
8 changes: 4 additions & 4 deletions internal/cmd/skupper/debug/sweeper/ports.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ import (
"strconv"
"strings"
"text/tabwriter"

"github.com/skupperproject/skupper/internal/ports"
)

// PortStat is the number of TCP adaptor connections on one router port, split
Expand All @@ -20,6 +18,8 @@ type PortStat struct {
Out int
}

const MaxTCPPort int = 65535

func (p PortStat) Total() int { return p.In + p.Out }

// ListPorts summarizes the router's TCP adaptor connections by port,
Expand Down Expand Up @@ -59,8 +59,8 @@ func FilterByPorts(conns []connInfo, portList []int) []connInfo {
func ValidatePorts(portList []int) error {
var portErrors []error
for _, p := range portList {
if p < 1 || p > ports.MAX_PORT {
portErrors = append(portErrors, fmt.Errorf("port is not valid: %d is not between 1 and %d", p, ports.MAX_PORT))
if p < 1 || p > MaxTCPPort {
portErrors = append(portErrors, fmt.Errorf("port is not valid: %d is not between 1 and %d", p, MaxTCPPort))
}
}
return errors.Join(portErrors...)
Expand Down
4 changes: 3 additions & 1 deletion internal/cmd/skupper/debug/sweeper/ports_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"bytes"
"reflect"
"testing"

"github.com/skupperproject/skupper/internal/ports"
)

func TestSummarizePorts(t *testing.T) {
Expand Down Expand Up @@ -115,7 +117,7 @@ func TestFilterByPorts(t *testing.T) {
}

func TestValidatePorts(t *testing.T) {
if err := ValidatePorts([]int{1, 8080, 65535}); err != nil {
if err := ValidatePorts([]int{1, 8080, ports.MAX_PORT}); err != nil {
t.Errorf("ValidatePorts() rejected valid ports: %v", err)
}
for _, invalid := range [][]int{{0}, {-1}, {65536}, {8080, 70000}} {
Expand Down
5 changes: 5 additions & 0 deletions internal/cmd/skupper/link/kube/link_generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"context"
"errors"
"fmt"
"slices"
"strconv"
"strings"
"time"
Expand Down Expand Up @@ -313,6 +314,10 @@ func getEndpointsByGroups(endpointList []v2alpha1.Endpoint) map[string][]v2alpha
endpointGroup := make(map[string][]v2alpha1.Endpoint)

for _, endpoint := range endpointList {
// ignore endpoints not used for site linking
if !slices.Contains([]string{"inter-router", "edge"}, endpoint.Name) {
continue
}
if len(endpointGroup[endpoint.Group]) > 0 {
endpointGroup[endpoint.Group] = append(endpointGroup[endpoint.Group], endpoint)
} else {
Expand Down
13 changes: 13 additions & 0 deletions internal/fixtures/skupper_resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,3 +176,16 @@ func SecuredAccess(name string, namespace string) *skupperv2alpha1.SecuredAccess
},
}
}

func Link(name, namespace string) *skupperv2alpha1.Link {
return &skupperv2alpha1.Link{
TypeMeta: metav1.TypeMeta{
APIVersion: "skupper.io/v2alpha1",
Kind: "Link",
},
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
},
}
}
3 changes: 3 additions & 0 deletions internal/kube/adaptor/config_sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ func (c *ConfigSync) configEvent(key string, configmap *corev1.ConfigMap) error
if err != nil {
return err
}
if err := qdr.SyncNetwork(c.agentPool, desired.Network); err != nil {
return err
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
if err := c.syncSslProfileCredentialsToDisk(desired.SslProfiles); err != nil {
return err
}
Expand Down
11 changes: 11 additions & 0 deletions internal/kube/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
openshiftroute "github.com/openshift/client-go/route/clientset/versioned"

routev1client "github.com/openshift/client-go/route/clientset/versioned/typed/route/v1"
crdClient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/client-go/discovery"
Expand Down Expand Up @@ -68,6 +69,7 @@ type Clients interface {
GetRouteInterface() openshiftroute.Interface
GetRouteClient() routev1client.RouteV1Interface
GetSkupperClient() skupperclient.Interface
GetCrdClient() crdClient.Interface
}

// A Kube Client manages orchestration and communications with the network components
Expand All @@ -81,6 +83,7 @@ type KubeClient struct {
Dynamic dynamic.Interface
Discovery discovery.DiscoveryInterface
Skupper skupperclient.Interface
CrdClient crdClient.Interface
}

func (c *KubeClient) GetNamespace() string {
Expand Down Expand Up @@ -111,6 +114,10 @@ func (c *KubeClient) GetSkupperClient() skupperclient.Interface {
return c.Skupper
}

func (c *KubeClient) GetCrdClient() crdClient.Interface {
return c.CrdClient
}

func NewClient(namespace string, context string, kubeConfigPath string) (*KubeClient, error) {
loadingRules := clientcmd.NewDefaultClientConfigLoadingRules()
if kubeConfigPath != "" {
Expand Down Expand Up @@ -185,6 +192,10 @@ func NewClientFromRestConfig(restconfig *restclient.Config, namespace string) (*
if err != nil {
return nil, err
}
c.CrdClient, err = crdClient.NewForConfig(cfg)
if err != nil {
return nil, err
}

return c, nil
}
49 changes: 49 additions & 0 deletions internal/kube/client/crds.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package client

import (
"context"
"strings"

apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
"k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func IsCrdAvailable(client clientset.Interface, name string) bool {
crd, err := getCrd(client, name)
return err == nil && crd != nil
}

func IsCrdPathAvailable(client clientset.Interface, name string, path string) bool {
crd, err := getCrd(client, name)
if err != nil {
return false
}
paths := strings.Split(path, ".")
for _, crdVersion := range crd.Spec.Versions {
if crdVersion.Schema == nil || crdVersion.Schema.OpenAPIV3Schema == nil {
continue
}
schema := crdVersion.Schema.OpenAPIV3Schema
properties := schema.Properties
found := true
for _, item := range paths {
if prop, ok := properties[item]; !ok {
found = false
break
} else {
properties = prop.Properties
}
}
if found {
return true
}
}
return false
}

func getCrd(client clientset.Interface, name string) (*apiextensionsv1.CustomResourceDefinition, error) {
crd, err := client.ApiextensionsV1().CustomResourceDefinitions().Get(
context.Background(), name, v1.GetOptions{})
return crd, err
}
Loading
Loading