Skip to content

Commit

Permalink
Add EnsureNetworksAnnotation as an alternative for CreateNetworksAnno…
Browse files Browse the repository at this point in the history
…tation

For BGP setup there is the need to set the default gateway
to the additional interface defined via the multus annotations.
To allow this a used can configure `ipam.gateway` in the NAD.
CreateNetworksAnnotation() will override the default by
reading the NAD and if `ipam.gateway` is defined and not "",
it gets set on the networks annotation as the `default-route`.

Jira: https://issues.redhat.com/browse/OSPRH-8680

Signed-off-by: Martin Schuppert <[email protected]>
  • Loading branch information
stuggi committed Nov 11, 2024
1 parent 71a0e9d commit 8021f07
Show file tree
Hide file tree
Showing 5 changed files with 182 additions and 0 deletions.
3 changes: 3 additions & 0 deletions modules/common/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ require (
github.com/onsi/gomega v1.34.1
github.com/openshift/api v3.9.0+incompatible
github.com/pkg/errors v0.9.1
github.com/tidwall/gjson v1.18.0
go.uber.org/zap v1.27.0
gopkg.in/yaml.v3 v3.0.1
k8s.io/api v0.29.10
Expand Down Expand Up @@ -52,6 +53,8 @@ require (
github.com/prometheus/common v0.45.0 // indirect
github.com/prometheus/procfs v0.12.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect
golang.org/x/net v0.28.0 // indirect
Expand Down
6 changes: 6 additions & 0 deletions modules/common/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,12 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
Expand Down
46 changes: 46 additions & 0 deletions modules/common/networkattachment/networkattachment.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@ import (
"context"
"encoding/json"
"fmt"
"net"

networkv1 "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1"
"github.com/openstack-k8s-operators/lib-common/modules/common/helper"
"github.com/openstack-k8s-operators/lib-common/modules/common/pod"
"github.com/tidwall/gjson"
"k8s.io/apimachinery/pkg/types"
)

Expand Down Expand Up @@ -136,3 +138,47 @@ func VerifyNetworkStatusFromAnnotation(

return networkReady, networkAttachmentStatus, nil
}

// EnsureNetworksAnnotation returns pod annotation for network-attachment-definition list
// e.g. k8s.v1.cni.cncf.io/networks: '[{"name": "internalapi", "namespace": "openstack"},{"name": "storage", "namespace": "openstack"}]'
// If `ipam.gateway` is defined in the NAD, the annotation wil contain
func EnsureNetworksAnnotation(
nadList []networkv1.NetworkAttachmentDefinition,
) (map[string]string, error) {

annotationString := map[string]string{}
netAnnotations := []networkv1.NetworkSelectionElement{}
for _, nad := range nadList {
cniConfig := nad.Spec.Config
gateway := ""
if gjson.Get(cniConfig, "ipam.gateway").Exists() &&
gjson.Get(cniConfig, "ipam.gateway").String() != "" {
gateway = gjson.Get(cniConfig, "ipam.gateway").String()
}

gatewayReq := []net.IP{}
if gateway != "" {
gatewayReq = append(gatewayReq, net.ParseIP(gateway))

}

netAnnotations = append(
netAnnotations,
networkv1.NetworkSelectionElement{
Name: nad.Name,
Namespace: nad.Namespace,
InterfaceRequest: GetNetworkIFName(nad.Name),
GatewayRequest: gatewayReq,
},
)
}

networks, err := json.Marshal(netAnnotations)
if err != nil {
return nil, fmt.Errorf("failed to encode networks %v into json: %w", nadList, err)
}

annotationString[networkv1.NetworkAttachmentAnnot] = string(networks)

return annotationString, nil
}
122 changes: 122 additions & 0 deletions modules/common/networkattachment/networkattachment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"testing"

networkv1 "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

. "github.com/onsi/gomega"
)
Expand Down Expand Up @@ -169,3 +170,124 @@ func TestGetNetworkIFName(t *testing.T) {
})
}
}

func TestEnsureNetworksAnnotation(t *testing.T) {

tests := []struct {
name string
nadList []networkv1.NetworkAttachmentDefinition
want map[string]string
}{
{
name: "No network",
nadList: []networkv1.NetworkAttachmentDefinition{},
want: map[string]string{networkv1.NetworkAttachmentAnnot: "[]"},
},
{
name: "Single network",
nadList: []networkv1.NetworkAttachmentDefinition{
{
ObjectMeta: metav1.ObjectMeta{Name: "one", Namespace: "foo"},
Spec: networkv1.NetworkAttachmentDefinitionSpec{
Config: `
{
"cniVersion": "0.3.1",
"name": "internalapi",
"type": "macvlan",
"master": "internalapi",
"ipam": {
"type": "whereabouts",
"range": "172.17.0.0/24",
"range_start": "172.17.0.30",
"range_end": "172.17.0.70"
}
}
`,
},
},
},
want: map[string]string{networkv1.NetworkAttachmentAnnot: "[{\"name\":\"one\",\"namespace\":\"foo\",\"interface\":\"one\"}]"},
},
{
name: "Multiple networks",
nadList: []networkv1.NetworkAttachmentDefinition{
{
ObjectMeta: metav1.ObjectMeta{Name: "one", Namespace: "foo"},
Spec: networkv1.NetworkAttachmentDefinitionSpec{
Config: `
{
"cniVersion": "0.3.1",
"name": "internalapi",
"type": "macvlan",
"master": "internalapi",
"ipam": {
"type": "whereabouts",
"range": "172.17.0.0/24",
"range_start": "172.17.0.30",
"range_end": "172.17.0.70"
}
}
`,
},
},
{
ObjectMeta: metav1.ObjectMeta{Name: "two", Namespace: "foo"},
Spec: networkv1.NetworkAttachmentDefinitionSpec{
Config: `
{
"cniVersion": "0.3.1",
"name": "tenant",
"type": "macvlan",
"master": "tenant",
"ipam": {
"type": "whereabouts",
"range": "172.19.0.0/24",
"range_start": "172.19.0.30",
"range_end": "172.19.0.70"
}
}
`,
},
},
},
want: map[string]string{networkv1.NetworkAttachmentAnnot: "[{\"name\":\"one\",\"namespace\":\"foo\",\"interface\":\"one\"},{\"name\":\"two\",\"namespace\":\"foo\",\"interface\":\"two\"}]"},
},
{
name: "With gateway defined",
nadList: []networkv1.NetworkAttachmentDefinition{
{
ObjectMeta: metav1.ObjectMeta{Name: "one", Namespace: "foo"},
Spec: networkv1.NetworkAttachmentDefinitionSpec{
Config: `
{
"cniVersion": "0.3.1",
"name": "internalapi",
"type": "macvlan",
"master": "internalapi",
"ipam": {
"type": "whereabouts",
"range": "172.17.0.0/24",
"range_start": "172.17.0.30",
"range_end": "172.17.0.70",
"gateway": "172.17.0.1"
}
}
`,
},
},
},
want: map[string]string{networkv1.NetworkAttachmentAnnot: "[{\"name\":\"one\",\"namespace\":\"foo\",\"interface\":\"one\",\"default-route\":[\"172.17.0.1\"]}]"},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
g := NewWithT(t)

networkAnnotation, err := EnsureNetworksAnnotation(tt.nadList)
g.Expect(err).NotTo(HaveOccurred())
g.Expect(networkAnnotation).To(HaveLen(len(tt.want)))
g.Expect(networkAnnotation).To(BeEquivalentTo(tt.want))
})
}
}
5 changes: 5 additions & 0 deletions modules/storage/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 8021f07

Please sign in to comment.