Skip to content

Commit

Permalink
Add ipsec e2e tests
Browse files Browse the repository at this point in the history
This adds relevant ipsec e2e tests to validate both control plane
and dataplane for both east west and north south traffic scenarios.

Signed-off-by: Periyasamy Palanisamy <pepalani@redhat.com>
  • Loading branch information
pperiyasamy committed Mar 15, 2024
1 parent f2cc4d0 commit cf28de5
Show file tree
Hide file tree
Showing 910 changed files with 67,183 additions and 28,941 deletions.
28 changes: 15 additions & 13 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
module github.com/openshift/origin

go 1.20
go 1.21

toolchain go1.21.1

require (
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0
Expand All @@ -24,10 +26,10 @@ require (
github.com/onsi/ginkgo/v2 v2.13.0
github.com/onsi/gomega v1.29.0
github.com/opencontainers/go-digest v1.0.0
github.com/openshift/api v0.0.0-20231218131639-7a5aa77cc72d
github.com/openshift/api v0.0.0-20240315040729-3b0a3e66537a
github.com/openshift/apiserver-library-go v0.0.0-20231218150122-47b436d2f389
github.com/openshift/build-machinery-go v0.0.0-20220913142420-e25cf57ea46d
github.com/openshift/client-go v0.0.0-20231218155125-ff7d9f9bf415
github.com/openshift/client-go v0.0.0-20240312121557-60dd5f9fbf8d
github.com/openshift/cluster-network-operator v0.0.0-20240111190956-90754aa19843
github.com/openshift/library-go v0.0.0-20240123164245-c92e150237e3
github.com/pborman/uuid v1.2.0
Expand All @@ -43,28 +45,28 @@ require (
github.com/stretchr/testify v1.8.4
go.etcd.io/etcd/client/pkg/v3 v3.5.10
go.etcd.io/etcd/client/v3 v3.5.10
golang.org/x/crypto v0.14.0
golang.org/x/net v0.17.0
golang.org/x/crypto v0.21.0
golang.org/x/net v0.22.0
golang.org/x/oauth2 v0.10.0
google.golang.org/grpc v1.58.3
gopkg.in/src-d/go-git.v4 v4.13.1
gopkg.in/yaml.v2 v2.4.0
k8s.io/api v0.29.0
k8s.io/api v0.29.2
k8s.io/apiextensions-apiserver v0.29.0
k8s.io/apimachinery v0.29.0
k8s.io/apimachinery v0.29.2
k8s.io/apiserver v0.29.0
k8s.io/cli-runtime v0.29.0
k8s.io/client-go v0.29.0
k8s.io/component-base v0.29.0
k8s.io/component-helpers v0.29.0
k8s.io/klog/v2 v2.110.1
k8s.io/klog/v2 v2.120.1
k8s.io/kube-aggregator v0.29.0
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00
k8s.io/kubectl v0.29.0
k8s.io/kubernetes v1.29.0
k8s.io/legacy-cloud-providers v0.29.0
k8s.io/pod-security-admission v0.29.0
k8s.io/utils v0.0.0-20230726121419-3b25d923346b
k8s.io/utils v0.0.0-20240310230437-4693a0247e57
sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3
sigs.k8s.io/structured-merge-diff/v4 v4.4.1
sigs.k8s.io/yaml v1.3.0
Expand Down Expand Up @@ -130,7 +132,7 @@ require (
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/go-asn1-ber/asn1-ber v1.5.4 // indirect
github.com/go-errors/errors v1.4.2 // indirect
github.com/go-logr/logr v1.3.0 // indirect
github.com/go-logr/logr v1.4.1 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/jsonpointer v0.19.6 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect
Expand Down Expand Up @@ -253,9 +255,9 @@ require (
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect
golang.org/x/mod v0.12.0 // indirect
golang.org/x/sync v0.3.0 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/term v0.13.0 // indirect
golang.org/x/text v0.13.0 // indirect
golang.org/x/sys v0.18.0 // indirect
golang.org/x/term v0.18.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/time v0.3.0 // indirect
golang.org/x/tools v0.12.0 // indirect
google.golang.org/api v0.126.0 // indirect
Expand Down
57 changes: 37 additions & 20 deletions go.sum

Large diffs are not rendered by default.

220 changes: 220 additions & 0 deletions test/extended/networking/ipsec.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
package networking

import (
"context"
"fmt"
"time"

configv1 "github.com/openshift/api/config/v1"
mcfgv1 "github.com/openshift/api/machineconfiguration/v1"
v1 "github.com/openshift/api/operator/v1"
exutil "github.com/openshift/origin/test/extended/util"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/client-go/util/retry"
"k8s.io/kubernetes/test/e2e/framework"
admissionapi "k8s.io/pod-security-admission/api"

g "github.com/onsi/ginkgo/v2"
m "github.com/onsi/gomega"
)

func configureIPsec(oc *exutil.CLI, ipsecMode v1.IPsecMode) error {
return retry.RetryOnConflict(retry.DefaultRetry, func() error {
network, err := oc.AdminOperatorClient().OperatorV1().Networks().Get(context.Background(), "cluster", metav1.GetOptions{})
if err != nil {
return err
}
if network.Spec.DefaultNetwork.OVNKubernetesConfig.IPsecConfig == nil {
network.Spec.DefaultNetwork.OVNKubernetesConfig.IPsecConfig = &v1.IPsecConfig{Mode: ipsecMode}
} else if network.Spec.DefaultNetwork.OVNKubernetesConfig.IPsecConfig.Mode != ipsecMode {
network.Spec.DefaultNetwork.OVNKubernetesConfig.IPsecConfig.Mode = ipsecMode
}
_, err = oc.AdminOperatorClient().OperatorV1().Networks().Update(context.Background(), network, metav1.UpdateOptions{})
return err
})
}

func isIPsecRolloutComplete(oc *exutil.CLI) (bool, error) {
for {
done, err := isMachineConfigPoolReadyWithIPsec(oc)
if err != nil {
return false, err
}
if done {
ready, err := ensureClusterOperatorsReady((oc))
if err != nil {
return false, err
}
if ready {
return true, nil
}
}
time.Sleep(180 * time.Second)
}
}

func ensureIPsecDisabled(oc *exutil.CLI) (bool, error) {
for {
running, err := isIPsecDaemonSetRunning(oc)
if err != nil {
return false, err
}
if !running {
ready, err := ensureClusterOperatorsReady((oc))
if err != nil {
return false, err
}
if ready {
return true, nil
}
}
time.Sleep(180 * time.Second)
}
}

func isMachineConfigPoolReadyWithIPsec(oc *exutil.CLI) (bool, error) {
masterIPsecMachineConfigs, err := findIPsecMachineConfigsWithLabel(oc, "machineconfiguration.openshift.io/role=master")
if err != nil {
return false, fmt.Errorf("failed to get ipsec machine configs for master: %v", err)
}
masterMCPool, err := oc.MachineConfigurationClient().MachineconfigurationV1().MachineConfigPools().Get(context.Background(),
"master", metav1.GetOptions{})
if err != nil {
return false, fmt.Errorf("failed to get ipsec machine config pool for master: %v", err)
}
if !hasSourceInMachineConfigStatus(masterMCPool.Status, masterIPsecMachineConfigs) {
return false, nil
}

workerIPsecMachineConfigs, err := findIPsecMachineConfigsWithLabel(oc, "machineconfiguration.openshift.io/role=worker")
if err != nil {
return false, fmt.Errorf("failed to get ipsec machine configs for worker: %v", err)
}
workerMCPool, err := oc.MachineConfigurationClient().MachineconfigurationV1().MachineConfigPools().Get(context.Background(),
"worker", metav1.GetOptions{})
if err != nil {
return false, fmt.Errorf("failed to get ipsec machine config pool for worker: %v", err)
}
if !hasSourceInMachineConfigStatus(workerMCPool.Status, workerIPsecMachineConfigs) {
return false, nil
}
return true, nil
}

func findIPsecMachineConfigsWithLabel(oc *exutil.CLI, selector string) ([]*mcfgv1.MachineConfig, error) {
lSelector, err := labels.Parse(selector)
if err != nil {
return nil, err
}
machineConfigs, err := oc.MachineConfigurationClient().MachineconfigurationV1().MachineConfigs().List(context.Background(),
metav1.ListOptions{LabelSelector: lSelector.String()})
if err != nil {
return nil, err
}
var ipsecMachineConfigs []*mcfgv1.MachineConfig
for i, machineConfig := range machineConfigs.Items {
if sets.New(machineConfig.Spec.Extensions...).Has("ipsec") {
ipsecMachineConfigs = append(ipsecMachineConfigs, &machineConfigs.Items[i])
}
}
return ipsecMachineConfigs, nil
}

func hasSourceInMachineConfigStatus(machineConfigStatus mcfgv1.MachineConfigPoolStatus, machineConfigs []*mcfgv1.MachineConfig) bool {
sourceNames := sets.New[string]()
for _, machineConfig := range machineConfigs {
sourceNames.Insert(machineConfig.Name)
}
for _, source := range machineConfigStatus.Configuration.Source {
if sourceNames.Has(source.Name) {
return true
}
}
return false
}

func ensureClusterOperatorsReady(oc *exutil.CLI) (bool, error) {
cos, err := oc.AdminConfigClient().ConfigV1().ClusterOperators().List(context.Background(), metav1.ListOptions{})
if err != nil {
return false, err
}
for _, co := range cos.Items {
available, degraded, progressing := false, true, true
for _, condition := range co.Status.Conditions {
isConditionTrue := condition.Status == configv1.ConditionTrue
switch condition.Type {
case configv1.OperatorAvailable:
available = isConditionTrue
case configv1.OperatorDegraded:
degraded = isConditionTrue
case configv1.OperatorProgressing:
progressing = isConditionTrue
}
}
isCOReady := available && !degraded && !progressing
if !isCOReady {
return false, nil
}
}
return true, nil
}

func isIPsecDaemonSetRunning(oc *exutil.CLI) (bool, error) {
ipsecDS, err := oc.KubeClient().AppsV1().DaemonSets("openshift-ovn-kubernetes").Get(context.Background(), "ovn-ipsec-host", metav1.GetOptions{})
if err != nil && apierrors.IsNotFound(err) {
return false, nil
} else if err != nil {
return false, err
}
ready := ipsecDS.Status.DesiredNumberScheduled == ipsecDS.Status.NumberReady
return ready, nil
}

var _ = g.Describe("[sig-network][Feature:IPsec]", func() {

oc := exutil.NewCLIWithPodSecurityLevel("ipsec-e2e", admissionapi.LevelBaseline)

InOVNKubernetesContext(func() {
g.BeforeAll(func() {
ready, err := ensureClusterOperatorsReady((oc))
framework.ExpectNoError(err)
m.Expect(ready).Should(m.Equal(true))

err = configureIPsec(oc, v1.IPsecModeFull)
framework.ExpectNoError(err)

ready, err = isIPsecRolloutComplete(oc)
framework.ExpectNoError(err)
m.Expect(ready).Should(m.Equal(true))
})

g.AfterAll(func() {
ready, err := ensureClusterOperatorsReady((oc))
framework.ExpectNoError(err)
m.Expect(ready).Should(m.Equal(true))

err = configureIPsec(oc, v1.IPsecModeDisabled)
framework.ExpectNoError(err)

disabled, err := ensureIPsecDisabled(oc)
framework.ExpectNoError(err)
m.Expect(disabled).Should(m.Equal(true))
})

g.It("ensure traffic between local pod to a remote pod is IPsec encrypted [apigroup:config.openshift.io] [Serial]", func() {
// TODO
})

g.It("ensure traffic between local pod to a ClusterIP service is IPsec encrypted [apigroup:config.openshift.io] [Serial]", func() {
// TODO
})

g.It("ensure external traffic to the cluster is IPsec encrypted [apigroup:config.openshift.io] [Serial]", func() {
// TODO
})

})
})
5 changes: 5 additions & 0 deletions test/extended/util/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ import (
buildv1client "github.com/openshift/client-go/build/clientset/versioned"
configv1client "github.com/openshift/client-go/config/clientset/versioned"
imagev1client "github.com/openshift/client-go/image/clientset/versioned"
mcv1client "github.com/openshift/client-go/machineconfiguration/clientset/versioned"
oauthv1client "github.com/openshift/client-go/oauth/clientset/versioned"
operatorv1client "github.com/openshift/client-go/operator/clientset/versioned"
projectv1client "github.com/openshift/client-go/project/clientset/versioned"
Expand Down Expand Up @@ -701,6 +702,10 @@ func (c *CLI) AdminTemplateClient() templatev1client.Interface {
return templatev1client.NewForConfigOrDie(c.AdminConfig())
}

func (c *CLI) MachineConfigurationClient() mcv1client.Interface {
return mcv1client.NewForConfigOrDie(c.AdminConfig())
}

// KubeClient provides a Kubernetes client for the current namespace
func (c *CLI) KubeClient() kubernetes.Interface {
return kubernetes.NewForConfigOrDie(c.UserConfig())
Expand Down

0 comments on commit cf28de5

Please sign in to comment.