Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • eclipse-research-labs/nemo-project/nemo-infrastructure-management/federated-meta-network-cluster-controller/multi-domain-l2s-m
1 result
Show changes
Showing
with 317 additions and 379 deletions
# Copyright 2024 Universidad Carlos III de Madrid
#
# 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.
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
name: veth5
labels:
app: l2sm
spec:
config: '{
"cniVersion": "0.3.0",
"type": "bridge",
"bridge": "br5",
"mtu": 1400,
"device": "veth5",
"ipam": {
"type":"static"
}
}'
# Copyright 2024 Universidad Carlos III de Madrid
#
# 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.
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
name: veth6
labels:
app: l2sm
spec:
config: '{
"cniVersion": "0.3.0",
"type": "bridge",
"bridge": "br6",
"mtu": 1400,
"device": "veth6",
"ipam": {
"type":"static"
}
}'
# Copyright 2024 Universidad Carlos III de Madrid
#
# 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.
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
name: veth7
labels:
app: l2sm
spec:
config: '{
"cniVersion": "0.3.0",
"type": "bridge",
"bridge": "br7",
"mtu": 1400,
"device": "veth7",
"ipam": {
"type":"static"
}
}'
# Copyright 2024 Universidad Carlos III de Madrid
#
# 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.
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
name: veth8
labels:
app: l2sm
spec:
config: '{
"cniVersion": "0.3.0",
"type": "bridge",
"bridge": "br8",
"mtu": 1400,
"device": "veth8",
"ipam": {
"type":"static"
}
}'
# Copyright 2024 Universidad Carlos III de Madrid
#
# 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.
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
name: veth9
labels:
app: l2sm
spec:
config: '{
"cniVersion": "0.3.0",
"type": "bridge",
"bridge": "br9",
"mtu": 1400,
"device": "veth9",
"ipam": {
"type":"static"
}
}'
......@@ -23,7 +23,6 @@ metadata:
app.kubernetes.io/part-of: controllermanager
app.kubernetes.io/managed-by: kustomize
name: webhook-service
namespace: l2sm-system
spec:
ports:
- port: 443
......
# Copyright 2024 Universidad Carlos III de Madrid
#
# 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.
 
---
apiVersion: v1
......@@ -4766,26 +4780,11 @@ spec:
spec:
description: OverlaySpec defines the desired state of Overlay
properties:
neighbors:
description: Field exclusive to the multi-domain overlay type. If
specified in other types of overlays, the reosurce will launch
an error and won't be created.
items:
properties:
domain:
description: |-
Domain where the neighbor's NED switch can be reached at. Must be a valid IP Address or Domain name, reachable from the node the NED
is going to be deployed at.
type: string
node:
description: Name of the cluster the link is going to be made
upon.
type: string
required:
- domain
- node
type: object
type: array
interfaceNumber:
default: 10
description: Interface number specifies how many interfaces the switch
should have predefined (if used with multus)
type: integer
networkController:
description: The SDN Controller that manages the overlay network.
Must specify a domain and a name.
......@@ -9390,6 +9389,18 @@ rules:
- patch
- update
- watch
- apiGroups:
- ""
resources:
- configmaps
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- ""
resources:
......@@ -9416,6 +9427,30 @@ rules:
- get
- patch
- update
- apiGroups:
- ""
resources:
- services
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- k8s.cni.cncf.io
resources:
- network-attachment-definitions
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- l2sm.l2sm.k8s.local
resources:
......@@ -9736,9 +9771,7 @@ spec:
value: l2sm-controller-service.l2sm-system.svc.cluster.local
- name: CONTROLLER_PORT
value: "8181"
- name: SWITCHES_NAMESPACE
value: l2sm-system
image: alexdecb/l2sm-controller-manager:2.7.1
image: alexdecb/l2sm-controller-manager:2.7.2
livenessProbe:
httpGet:
path: /healthz
......@@ -9879,113 +9912,3 @@ webhooks:
resources:
- pods
sideEffects: None
---
apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
labels:
app: l2sm
name: veth1
namespace: l2sm-system
spec:
config: '{ "cniVersion": "0.3.0", "type": "bridge", "bridge": "br1", "mtu": 1400,
"device": "veth1", "ipam": { "type":"static" } }'
---
apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
labels:
app: l2sm
name: veth10
namespace: l2sm-system
spec:
config: '{ "cniVersion": "0.3.0", "type": "bridge", "bridge": "br10", "mtu": 1400,
"device": "veth10", "ipam": { "type":"static" } }'
---
apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
labels:
app: l2sm
name: veth2
namespace: l2sm-system
spec:
config: '{ "cniVersion": "0.3.0", "type": "bridge", "bridge": "br2", "mtu": 1400,
"device": "veth2", "ipam": { "type":"static" } }'
---
apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
labels:
app: l2sm
name: veth3
namespace: l2sm-system
spec:
config: '{ "cniVersion": "0.3.0", "type": "bridge", "bridge": "br3", "mtu": 1400,
"device": "veth3", "ipam": { "type":"static" } }'
---
apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
labels:
app: l2sm
name: veth4
namespace: l2sm-system
spec:
config: '{ "cniVersion": "0.3.0", "type": "bridge", "bridge": "br4", "mtu": 1400,
"device": "veth4", "ipam": { "type":"static" } }'
---
apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
labels:
app: l2sm
name: veth5
namespace: l2sm-system
spec:
config: '{ "cniVersion": "0.3.0", "type": "bridge", "bridge": "br5", "mtu": 1400,
"device": "veth5", "ipam": { "type":"static" } }'
---
apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
labels:
app: l2sm
name: veth6
namespace: l2sm-system
spec:
config: '{ "cniVersion": "0.3.0", "type": "bridge", "bridge": "br6", "mtu": 1400,
"device": "veth6", "ipam": { "type":"static" } }'
---
apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
labels:
app: l2sm
name: veth7
namespace: l2sm-system
spec:
config: '{ "cniVersion": "0.3.0", "type": "bridge", "bridge": "br7", "mtu": 1400,
"device": "veth7", "ipam": { "type":"static" } }'
---
apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
labels:
app: l2sm
name: veth8
namespace: l2sm-system
spec:
config: '{ "cniVersion": "0.3.0", "type": "bridge", "bridge": "br8", "mtu": 1400,
"device": "veth8", "ipam": { "type":"static" } }'
---
apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
labels:
app: l2sm
name: veth9
namespace: l2sm-system
spec:
config: '{ "cniVersion": "0.3.0", "type": "bridge", "bridge": "br9", "mtu": 1400,
"device": "veth9", "ipam": { "type":"static" } }'
......@@ -17,33 +17,32 @@ kind: Overlay
metadata:
name: overlay-sample
spec:
networkController:
name: l2sm-test-sdn
domain: "l2sm-controller-service.l2sm-system.svc"
topology:
nodes:
- l2sm1
- l2sm2
- l2sm-test-control-plane
- l2sm-test-worker
- l2sm-test-worker2
links:
- endpointA: l2sm1
endpointB: l2sm2
- endpointA: l2sm-test-worker
endpointB: l2sm-test-worker2
- endpointA: l2sm-test-worker
endpointB: l2sm-test-control-plane
- endpointA: l2sm-test-control-plane
endpointB: l2sm-test-worker2
switchTemplate:
spec:
containers:
- name: l2sm-switch
image: alexdecb/l2sm-switch:2.7
image: alexdecb/l2sm-switch:1.0.2
resources: {}
env:
- name: NODENAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: NVETHS
value: "10"
- name: CONTROLLERIP
value: "l2sm-controller-service"
- name: PODNAME
valueFrom:
fieldRef:
fieldPath: metadata.name
imagePullPolicy: Always
securityContext:
capabilities:
add: ["NET_ADMIN"]
......
......@@ -12,21 +12,21 @@
# See the License for the specific language governing permissions and
# limitations under the License.
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: l2sm-test
networking:
disableDefaultCNI: true # Disable Kindnet, we will use Flannel as the primary CNI plugin
podSubnet: "10.244.0.0/16" # Flannel requires this CIDR
nodes:
- role: control-plane
image: kindest/node:v1.26.6
extraPortMappings:
- containerPort: 30000
hostPort: 30000
protocol: TCP
- role: worker
image: kindest/node:v1.26.6
- role: worker
image: kindest/node:v1.26.6
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
name: veth3
labels:
app: l2sm
spec:
config: '{
"cniVersion": "0.3.0",
"type": "bridge",
"bridge": "br3",
"mtu": 1400,
"device": "veth3",
"ipam": {
"type":"static"
}
}'
......@@ -5,19 +5,33 @@ go 1.21.7
toolchain go1.22.5
require (
github.com/Networks-it-uc3m/l2sm-switch v1.0.2
github.com/go-logr/logr v1.4.1
github.com/onsi/ginkgo/v2 v2.14.0
github.com/onsi/gomega v1.30.0
github.com/stretchr/testify v1.9.0
google.golang.org/grpc v1.67.0
k8s.io/api v0.29.0
k8s.io/apimachinery v0.29.0
k8s.io/client-go v0.29.0
github.com/Networks-it-uc3m/l2sm-switch v1.0.0
sigs.k8s.io/controller-runtime v0.17.0
)
require google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect
require (
github.com/BurntSushi/toml v1.2.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/exp/typeparams v0.0.0-20221212164502-fae10dda9338 // indirect
golang.org/x/mod v0.20.0 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/telemetry v0.0.0-20240829154258-f29ab539cc98 // indirect
golang.org/x/tools/gopls v0.16.2 // indirect
golang.org/x/vuln v1.0.4 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect
honnef.co/go/tools v0.4.7 // indirect
mvdan.cc/gofumpt v0.6.0 // indirect
mvdan.cc/xurls/v2 v2.5.0 // indirect
)
// replace github.com/Networks-it-uc3m/l2sm-switch => ../switch
......@@ -65,7 +79,7 @@ require (
golang.org/x/term v0.23.0 // indirect
golang.org/x/text v0.17.0 // indirect
golang.org/x/time v0.3.0 // indirect
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
golang.org/x/tools v0.22.1-0.20240829175637-39126e24d653 // indirect
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
google.golang.org/protobuf v1.34.2 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
......
github.com/Networks-it-uc3m/l2sm-switch v1.0.0 h1:SQ2hFmObffhNV2jVSeSpqVGCm2/d6HZuQ02YzeCI+x0=
github.com/Networks-it-uc3m/l2sm-switch v1.0.0/go.mod h1:zcfUyOLAiCEQza5QRTJoQsrOYdu+WQf/6rQNmhGb4WQ=
github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak=
github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/Networks-it-uc3m/l2sm-switch v1.0.2 h1:P4gVqfcO6LgKVxWI4aDfQnbYnRi+8+nc5+K1wq9sIEU=
github.com/Networks-it-uc3m/l2sm-switch v1.0.2/go.mod h1:zcfUyOLAiCEQza5QRTJoQsrOYdu+WQf/6rQNmhGb4WQ=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
......@@ -124,8 +126,12 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA=
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA=
golang.org/x/exp/typeparams v0.0.0-20221212164502-fae10dda9338 h1:2O2DON6y3XMJiQRAS1UWU+54aec2uopH3x7MAiqGW6Y=
golang.org/x/exp/typeparams v0.0.0-20221212164502-fae10dda9338/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
......@@ -137,12 +143,16 @@ golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbht
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/telemetry v0.0.0-20240829154258-f29ab539cc98 h1:Wm3cG5X6sZ0RSVRc/H1/sciC4AT6HAKgLCSH2lbpR/c=
golang.org/x/telemetry v0.0.0-20240829154258-f29ab539cc98/go.mod h1:m7R/r+o5h7UvF2JD9n2iLSGY4v8v+zNSyTJ6xynLrqs=
golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU=
golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
......@@ -157,6 +167,12 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
golang.org/x/tools v0.22.1-0.20240829175637-39126e24d653 h1:6bJEg2w2kUHWlfdJaESYsmNfI1LKAZQi6zCa7LUn7eI=
golang.org/x/tools v0.22.1-0.20240829175637-39126e24d653/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
golang.org/x/tools/gopls v0.16.2 h1:K1z03MlikHfaMTtG01cUeL5FAOTJnITuNe0TWOcg8tM=
golang.org/x/tools/gopls v0.16.2/go.mod h1:Hj8YxzfHfFyRK5muTZy5oO6/0nL7CZWu28ZNac7tXF0=
golang.org/x/vuln v1.0.4 h1:SP0mPeg2PmGCu03V+61EcQiOjmpri2XijexKdzv8Z1I=
golang.org/x/vuln v1.0.4/go.mod h1:NbJdUQhX8jY++FtuhrXs2Eyx0yePo9pF7nPlIjo9aaQ=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
......@@ -182,6 +198,8 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.4.7 h1:9MDAWxMoSnB6QoSqiVr7P5mtkT9pOc1kSxchzPCnqJs=
honnef.co/go/tools v0.4.7/go.mod h1:+rnGS1THNh8zMwnd2oVOTL9QF6vmfyG6ZXBULae2uc0=
k8s.io/api v0.29.0 h1:NiCdQMY1QOp1H8lfRyeEf8eOwV6+0xA6XEE44ohDX2A=
k8s.io/api v0.29.0/go.mod h1:sdVmXoz2Bo/cb77Pxi71IPTSErEW32xa4aXwKH7gfBA=
k8s.io/apiextensions-apiserver v0.29.0 h1:0VuspFG7Hj+SxyF/Z/2T0uFbI5gb5LRgEyUVE3Q4lV0=
......@@ -198,6 +216,10 @@ k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/A
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA=
k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI=
k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
mvdan.cc/gofumpt v0.6.0 h1:G3QvahNDmpD+Aek/bNOLrFR2XC6ZAdo62dZu65gmwGo=
mvdan.cc/gofumpt v0.6.0/go.mod h1:4L0wf+kgIPZtcCWXynNS2e6bhmj73umwnuXSZarixzA=
mvdan.cc/xurls/v2 v2.5.0 h1:lyBNOm8Wo71UknhUs4QTFUNNMyxy2JEIaKKo0RWOh+8=
mvdan.cc/xurls/v2 v2.5.0/go.mod h1:yQgaGQ1rFtJUzkmKiHYSSfuQxqfYmd//X6PxvholpeE=
sigs.k8s.io/controller-runtime v0.17.0 h1:fjJQf8Ukya+VjogLO6/bNX9HE6Y2xpsO5+fyS26ur/s=
sigs.k8s.io/controller-runtime v0.17.0/go.mod h1:+MngTvIQQQhfXtwfdGw/UOQ/aIaqsYywfCINOtwMO/s=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
......
#!/bin/bash
git clone https://github.com/containernetworking/plugins.git
sed -i "s/go 1.23/go 1.23.0/g" ./plugins/go.mod # to avoid error after recent update
./plugins/build_linux.sh
# copy necessary plugins into all nodes
docker cp ./plugins/bin/. l2sm-test-control-plane:/opt/cni/bin
docker cp ./plugins/bin/. l2sm-test-worker:/opt/cni/bin
docker cp ./plugins/bin/. l2sm-test-worker2:/opt/cni/bin
docker exec -it l2sm-test-control-plane modprobe br_netfilter
docker exec -it l2sm-test-worker modprobe br_netfilter
docker exec -it l2sm-test-worker2 modprobe br_netfilter
docker exec -it l2sm-test-control-plane sysctl -p /etc/sysctl.conf
docker exec -it l2sm-test-worker sysctl -p /etc/sysctl.conf
docker exec -it l2sm-test-worker2 sysctl -p /etc/sysctl.conf
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
kubectl wait --for=condition=Ready pods -n kube-flannel -l app=flannel --timeout=300s
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.16.1/cert-manager.yaml
kubectl apply -f https://raw.githubusercontent.com/k8snetworkplumbingwg/multus-cni/master/deployments/multus-daemonset-thick.yml
kubectl wait --for=condition=Ready pods --all -A --timeout=300s
......@@ -22,6 +22,7 @@ import (
l2smv1 "github.com/Networks-it-uc3m/L2S-M/api/v1"
"github.com/Networks-it-uc3m/L2S-M/internal/utils"
switchv1 "github.com/Networks-it-uc3m/l2sm-switch/api/v1"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
......@@ -30,8 +31,6 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
"sigs.k8s.io/controller-runtime/pkg/log"
nedv1 "github.com/Networks-it-uc3m/l2sm-switch/api/v1"
)
// NetworkEdgeDeviceReconciler reconciles a NetworkEdgeDevice object
......@@ -168,13 +167,13 @@ func (r *NetworkEdgeDeviceReconciler) createExternalResources(ctx context.Contex
for i, neighbor := range netEdgeDevice.Spec.Neighbors {
neighbors[i] = neighbor.Domain
}
nedNeighbors, err := json.Marshal(nedv1.Node{Name: netEdgeDevice.Spec.NodeConfig.NodeName, NodeIP: netEdgeDevice.Spec.NodeConfig.IPAddress, NeighborNodes: neighbors})
nedNeighbors, err := json.Marshal(switchv1.Node{Name: netEdgeDevice.Spec.NodeConfig.NodeName, NodeIP: netEdgeDevice.Spec.NodeConfig.IPAddress, NeighborNodes: neighbors})
if err != nil {
return err
}
nedName := utils.GetBridgeName(utils.BridgeParams{NodeName: netEdgeDevice.Spec.NodeConfig.NodeName, ProviderName: netEdgeDevice.Spec.NetworkController.Name})
nedConfig, err := json.Marshal(nedv1.NedSettings{ControllerIP: netEdgeDevice.Spec.NetworkController.Domain, NodeName: netEdgeDevice.Spec.NodeConfig.NodeName, NedName: nedName})
nedConfig, err := json.Marshal(switchv1.NedSettings{ControllerIP: netEdgeDevice.Spec.NetworkController.Domain, NodeName: netEdgeDevice.Spec.NodeConfig.NodeName, NedName: nedName})
if err != nil {
return err
}
......
......@@ -22,6 +22,7 @@ import (
l2smv1 "github.com/Networks-it-uc3m/L2S-M/api/v1"
"github.com/Networks-it-uc3m/L2S-M/internal/utils"
nettypes "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
......@@ -30,6 +31,8 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
"sigs.k8s.io/controller-runtime/pkg/log"
switchv1 "github.com/Networks-it-uc3m/l2sm-switch/api/v1"
)
// OverlayReconciler reconciles a Overlay object
......@@ -40,11 +43,13 @@ type OverlayReconciler struct {
var replicaSetOwnerKeyOverlay = ".metadata.controller.overlay"
// +kubebuilder:rbac:groups=l2sm.l2sm.k8s.local,resources=replicasets,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=core,resources=configmaps,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=core,resources=services,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=apps,resources=replicasets,verbs=get;list;watch;create;update;patch;delete
//+kubebuilder:rbac:groups=l2sm.l2sm.k8s.local,resources=overlays,verbs=get;list;watch;create;update;patch;delete
//+kubebuilder:rbac:groups=l2sm.l2sm.k8s.local,resources=overlays/status,verbs=get;update;patch
//+kubebuilder:rbac:groups=l2sm.l2sm.k8s.local,resources=overlays/finalizers,verbs=update
// +kubebuilder:rbac:groups=k8s.cni.cncf.io,resources=network-attachment-definitions,verbs=get;list;watch;create;update;patch;delete
// Reconcile is part of the main kubernetes reconciliation loop which aims to
// move the current state of the cluster closer to the desired state.
......@@ -87,11 +92,11 @@ func (r *OverlayReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct
// The object is being deleted
if controllerutil.ContainsFinalizer(overlay, l2smFinalizer) {
// our finalizer is present, so lets handle any external dependency
// if err := r.deleteExternalResources(ctx, overlay); err != nil {
// // if fail to delete the external dependency here, return with error
// // so that it can be retried.
// return ctrl.Result{}, err
// }
if err := r.deleteExternalResources(ctx, overlay); err != nil {
// if fail to delete the external dependency here, return with error
// so that it can be retried.
return ctrl.Result{}, err
}
// remove our finalizer from the list and update it.
controllerutil.RemoveFinalizer(overlay, l2smFinalizer)
......@@ -153,10 +158,18 @@ func (r *OverlayReconciler) SetupWithManager(mgr ctrl.Manager) error {
Complete(r)
}
// func (r *OverlayReconciler) deleteExternalResources(ctx context.Context, overlay *l2smv1.Overlay) error {
func (r *OverlayReconciler) deleteExternalResources(ctx context.Context, overlay *l2smv1.Overlay) error {
opts := []client.DeleteAllOfOption{
client.InNamespace(overlay.Namespace),
client.MatchingLabels{"overlay": overlay.Name},
}
r.Client.DeleteAllOf(ctx, &nettypes.NetworkAttachmentDefinition{}, opts...)
return nil
}
// return nil
// }
type OverlayConfigJson struct {
ControllerIp string `json:"ControllerIp"`
}
type TopologySwitchJson struct {
Nodes []NodeJson `json:"Nodes"`
......@@ -174,21 +187,31 @@ func (r *OverlayReconciler) createExternalResources(ctx context.Context, overlay
constructConfigMapForOverlay := func(overlay *l2smv1.Overlay) (*corev1.ConfigMap, error) {
// Construct the TopologySwitchJson
topologySwitch := TopologySwitchJson{}
topologySwitch := switchv1.Topology{}
overlayConfig := switchv1.OverlaySettings{ControllerIp: overlay.Spec.NetworkController.Domain,
InterfacesNumber: overlay.Spec.InterfaceNumber,
OverlayName: overlay.Name}
overlayName := overlay.ObjectMeta.Name
// Populate Nodes
for _, nodeName := range overlay.Spec.Topology.Nodes {
node := NodeJson{
node := switchv1.Node{
Name: nodeName,
NodeIP: fmt.Sprintf("l2sm-switch-%s-%s", overlayName, nodeName),
NodeIP: utils.GenerateServiceName(overlayName, nodeName),
}
topologySwitch.Nodes = append(topologySwitch.Nodes, node)
}
// Populate Links
topologySwitch.Links = append(topologySwitch.Links, overlay.Spec.Topology.Links...)
for _, overlayLink := range overlay.Spec.Topology.Links {
link := switchv1.Link{
EndpointNodeA: overlayLink.EndpointA,
EndpointNodeB: overlayLink.EndpointB,
}
topologySwitch.Links = append(topologySwitch.Links, link)
}
// Convert TopologySwitchJson to JSON
topologyJSON, err := json.Marshal(topologySwitch)
......@@ -196,6 +219,10 @@ func (r *OverlayReconciler) createExternalResources(ctx context.Context, overlay
return nil, err
}
configJSON, err := json.Marshal(overlayConfig)
if err != nil {
return nil, err
}
configMap := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("%s-topology", overlay.Name),
......@@ -203,6 +230,7 @@ func (r *OverlayReconciler) createExternalResources(ctx context.Context, overlay
},
Data: map[string]string{
"topology.json": string(topologyJSON),
"config.json": string(configJSON),
},
}
if err := controllerutil.SetControllerReference(overlay, configMap, r.Scheme); err != nil {
......@@ -218,12 +246,12 @@ func (r *OverlayReconciler) createExternalResources(ctx context.Context, overlay
return err
}
constructNodeResourcesForOverlay := func(overlay *l2smv1.Overlay) ([]*appsv1.ReplicaSet, []*corev1.Service, error) {
constructNodeResourcesForOverlay := func(overlay *l2smv1.Overlay) ([]*appsv1.ReplicaSet, []*corev1.Service, []*nettypes.NetworkAttachmentDefinition, error) {
// Define volume mounts to be added to each container
volumeMounts := []corev1.VolumeMount{
{
Name: "topology",
Name: "config",
MountPath: "/etc/l2sm/",
ReadOnly: true,
},
......@@ -239,7 +267,7 @@ func (r *OverlayReconciler) createExternalResources(ctx context.Context, overlay
// Define the volume using the created ConfigMap
volumes := []corev1.Volume{
{
Name: "topology",
Name: "config",
VolumeSource: corev1.VolumeSource{
ConfigMap: &corev1.ConfigMapVolumeSource{
LocalObjectReference: corev1.LocalObjectReference{
......@@ -250,15 +278,46 @@ func (r *OverlayReconciler) createExternalResources(ctx context.Context, overlay
Key: "topology.json",
Path: "topology.json",
},
{
Key: "config.json",
Path: "config.json",
},
},
},
},
},
}
switchInterfacesAnnotations := GenerateAnnotations(overlay.Name, overlay.Spec.InterfaceNumber)
var networkAttachmentDefinitions []*nettypes.NetworkAttachmentDefinition
var auxNetAttachDef *nettypes.NetworkAttachmentDefinition
for i := 1; i <= overlay.Spec.InterfaceNumber; i++ {
auxNetAttachDef = &nettypes.NetworkAttachmentDefinition{
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("%s-veth%d", overlay.Name, i),
Namespace: overlay.Namespace,
Labels: map[string]string{"app": "l2sm", "overlay": overlay.Name},
},
Spec: nettypes.NetworkAttachmentDefinitionSpec{
Config: fmt.Sprintf(`{
"cniVersion": "0.3.0",
"type": "bridge",
"bridge": "%s-br%d",
"mtu": 1400,
"device": "%s-veth%d",
"ipam": {
"type":"static"
}
}`, "", i, overlay.Name, i),
},
}
networkAttachmentDefinitions = append(networkAttachmentDefinitions, auxNetAttachDef)
}
var replicaSets []*appsv1.ReplicaSet
var services []*corev1.Service
for _, node := range overlay.Spec.Topology.Nodes {
name := fmt.Sprintf("%s-%s-%s", "l2sm-switch", node, utils.GenerateHash(overlay))
......@@ -283,27 +342,7 @@ func (r *OverlayReconciler) createExternalResources(ctx context.Context, overlay
"app": name,
},
Annotations: map[string]string{
"k8s.v1.cni.cncf.io/networks": `[{
"name": "veth1", "ips": ["fe80::58d0:b8ff:fe42:debf/64"]
}, {
"name": "veth2", "ips": ["fe80::58d0:b8ff:fe42:debe/64"]
}, {
"name": "veth3", "ips": ["fe80::58d0:b8ff:fe42:debd/64"]
}, {
"name": "veth4", "ips": ["fe80::58d0:b8ff:fe42:debc/64"]
}, {
"name": "veth5", "ips": ["fe80::58d0:b8ff:fe42:debb/64"]
}, {
"name": "veth6", "ips": ["fe80::58d0:b8ff:fe42:deba/64"]
}, {
"name": "veth7", "ips": ["fe80::58d0:b8ff:fe42:deb9/64"]
}, {
"name": "veth8", "ips": ["fe80::58d0:b8ff:fe42:deb8/64"]
}, {
"name": "veth9", "ips": ["fe80::58d0:b8ff:fe42:deb7/64"]
}, {
"name": "veth10", "ips": ["fe80::58d0:b8ff:fe42:deb6/64"]
}]`,
MULTUS_ANNOTATION_KEY: switchInterfacesAnnotations,
},
},
Spec: corev1.PodSpec{
......@@ -324,7 +363,7 @@ func (r *OverlayReconciler) createExternalResources(ctx context.Context, overlay
replicaSet.Labels[k] = v
}
if err := controllerutil.SetControllerReference(overlay, replicaSet, r.Scheme); err != nil {
return nil, nil, err
return nil, nil, nil, err
}
replicaSets = append(replicaSets, replicaSet)
......@@ -332,7 +371,7 @@ func (r *OverlayReconciler) createExternalResources(ctx context.Context, overlay
// Create a headless service for the ReplicaSet
service := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("l2sm-switch-%s-%s", overlay.Name, node),
Name: utils.GenerateServiceName(overlay.Name, node),
Namespace: overlay.Namespace,
Labels: map[string]string{"app": name},
},
......@@ -349,20 +388,24 @@ func (r *OverlayReconciler) createExternalResources(ctx context.Context, overlay
}
if err := controllerutil.SetControllerReference(overlay, service, r.Scheme); err != nil {
return nil, nil, err
return nil, nil, nil, err
}
services = append(services, service)
}
return replicaSets, services, nil
return replicaSets, services, networkAttachmentDefinitions, nil
}
replicaSets, services, err := constructNodeResourcesForOverlay(overlay)
replicaSets, services, netAttachDefs, err := constructNodeResourcesForOverlay(overlay)
if err != nil {
return err
}
for _, netAttachDef := range netAttachDefs {
if err = r.Client.Create(ctx, netAttachDef); err != nil {
return err
}
}
for _, replicaSet := range replicaSets {
if err = r.Client.Create(ctx, replicaSet); err != nil {
return err
......
......@@ -150,9 +150,14 @@ func (r *PodReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.R
// Add the pod interfaces to the sdn controller
multusAnnotations, ok := pod.Annotations[MULTUS_ANNOTATION_KEY]
// if ok {
// logger.Info(multusAnnotations)
// return ctrl.Result{Requeue: true}, fmt.Errorf("back")
// }
if !ok {
logger.Error(nil, "Error detaching the pod from the network attachment definitions")
logger.Error(nil, "Error getting the pod network attachment definitions annotations")
return ctrl.Result{}, nil
}
......
......@@ -154,3 +154,26 @@ func (r *PodReconciler) DetachNetAttachDef(ctx context.Context, multusNetAttachD
return err
}
func GenerateAnnotations(overlayName string, ammount int) string {
annotationsString := []string{}
var newAnnotation string
for i := 1; i <= ammount; i++ {
newAnnotation = fmt.Sprintf(`{"name": "%s-veth%d", "ips": ["fe80::58d0:b8ff:fe%s:%s/64"]}`, overlayName, i, fmt.Sprintf("%02d", i), Generate4byteChunk())
annotationsString = append(annotationsString, newAnnotation)
}
return "[" + strings.Join(annotationsString, ",") + "]"
}
func Generate4byteChunk() string {
// Generating the interface ID (64 bits)
interfaceID := rand.Uint64() & 0xffff
// Formatting to a 4 character hexadecimal string
interfaceIDHex := fmt.Sprintf("%04x", interfaceID)
return interfaceIDHex
}
// Copyright 2024 Universidad Carlos III de Madrid
//
// 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.
// generate_test.go
package controller
import (
"regexp"
"testing"
)
// TestGenerate4byteChunk verifies that Generate4byteChunk produces a 4-character hexadecimal string.
func TestGenerate4byteChunk(t *testing.T) {
// Regular expression to match exactly 4 hexadecimal characters
re := regexp.MustCompile(`^[0-9a-fA-F]{4}$`)
// Call Generate4byteChunk multiple times to check if output is always 4 characters
for i := 0; i < 100; i++ {
output := Generate4byteChunk()
// Check if the output matches the 4-character hex pattern
if !re.MatchString(output) {
t.Errorf("Expected a 4-character hexadecimal string, but got: %s", output)
}
}
}
......@@ -20,6 +20,7 @@ import (
"crypto/sha256"
"encoding/hex"
"fmt"
"hash/fnv"
"strings"
"k8s.io/apimachinery/pkg/runtime"
......@@ -133,3 +134,11 @@ func GetBridgeName(params BridgeParams) string {
dpid := hex.EncodeToString(dpidBytes)
return fmt.Sprintf("br-%s", dpid)
}
func GenerateServiceName(overlayName, nodeName string) string {
hash := fnv.New32() // Using FNV hash for a compact hash, but still 32 bits
hash.Write([]byte(fmt.Sprintf("%s%s", overlayName, nodeName)))
sum := hash.Sum32()
// Encode the hash as a base32 string and take the first 4 characters
return fmt.Sprintf("l2sm-switch-%04x", sum) // H
}