Skip to content

Commit

Permalink
Add basic tests for secondary network metrics.
Browse files Browse the repository at this point in the history
Signed-off-by: Federico Paolinelli <fpaoline@redhat.com>
  • Loading branch information
fedepaol committed May 19, 2020
1 parent 5926461 commit bfb978d
Show file tree
Hide file tree
Showing 2 changed files with 188 additions and 2 deletions.
20 changes: 18 additions & 2 deletions test/extended/prometheus/prometheus.go
Original file line number Diff line number Diff line change
Expand Up @@ -425,14 +425,30 @@ var _ = g.Describe("[sig-instrumentation] Prometheus", func() {
oc.SetupProject()
ns := oc.Namespace()

execPod := exutil.CreateCentosExecPodOrFail(oc.AdminKubeClient(), ns, "execpod", nil)
cs, err := newDynClientSet()
o.Expect(err).NotTo(o.HaveOccurred())
err = addNetwork(cs, "secondary", ns)
o.Expect(err).NotTo(o.HaveOccurred())

defer func() {
err := removeNetwork(cs, "secondary", ns)
o.Expect(err).NotTo(o.HaveOccurred())
}()

execPod := exutil.CreateCentosExecPodOrFail(oc.AdminKubeClient(), ns, "execpod", func(pod *v1.Pod) {
pod.Annotations = map[string]string{
"k8s.v1.cni.cncf.io/networks": "secondary",
}
})

defer func() {
oc.AdminKubeClient().CoreV1().Pods(ns).Delete(context.Background(), execPod.Name, *metav1.NewDeleteOptions(1))
}()

g.By("verifying named metrics keys")
queries := map[string]bool{
fmt.Sprintf(`pod_network_name_info{pod="%s",namespace="%s",interface="eth0"} == 0`, execPod.Name, execPod.Namespace): true,
fmt.Sprintf(`pod_network_name_info{pod="%s",namespace="%s",interface="eth0"} == 0`, execPod.Name, execPod.Namespace): true,
fmt.Sprintf(`pod_network_name_info{pod="%s",namespace="%s",network_name="secondary"} == 0`, execPod.Name, execPod.Namespace): true,
}
helper.RunQueries(queries, oc, ns, execPod.Name, url, bearerToken)
})
Expand Down
170 changes: 170 additions & 0 deletions test/extended/prometheus/secondary_network.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
package prometheus

import (
"fmt"
"time"

"golang.org/x/net/context"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/dynamic"

e2e "k8s.io/kubernetes/test/e2e/framework"
)

type dynClientSet struct {
dc dynamic.Interface
}

func (dcs dynClientSet) Networks() dynamic.ResourceInterface {
return dcs.dc.Resource(schema.GroupVersionResource{Group: "operator.openshift.io", Resource: "networks", Version: "v1"})
}

func (dcs dynClientSet) NetworkAttachmentDefinitions(namespace string) dynamic.ResourceInterface {
return dcs.dc.Resource(schema.GroupVersionResource{Group: "k8s.cni.cncf.io", Resource: "network-attachment-definitions", Version: "v1"}).Namespace(namespace)
}

func newDynClientSet() (*dynClientSet, error) {
cfg, err := e2e.LoadConfig()
if err != nil {
return nil, err
}

dc, err := dynamic.NewForConfig(cfg)
if err != nil {
return nil, err
}

return &dynClientSet{
dc: dc,
}, nil
}

func addNetwork(client *dynClientSet, name, namespace string) error {
clusterNetwork, err := client.Networks().Get(context.Background(), "cluster", metav1.GetOptions{})
if err != nil {
return fmt.Errorf("Failed to get cluster network %v", err)
}

toUpdate := clusterNetwork.DeepCopy()
newSpec, ok := toUpdate.Object["spec"].(map[string]interface{})
if !ok {
return fmt.Errorf("Failed to fetch spec for cluster network")
}

nn, ok := newSpec["additionalNetworks"]
var newAdditionalNetworks []interface{}
if ok {
newAdditionalNetworks = nn.([]interface{})
} else {
newAdditionalNetworks = make([]interface{}, 0)
}

newAdditionalNetworks = append(newAdditionalNetworks, newMacVlan(name, namespace))
newSpec["additionalNetworks"] = newAdditionalNetworks

_, err = client.Networks().Update(context.Background(), toUpdate, metav1.UpdateOptions{})
if err != nil {
return fmt.Errorf("Failed to update cluster network %v", err)
}

err = waitForNetworkAttachmentDefinition(client, name, namespace)
if err != nil {
return fmt.Errorf("Failed waiting for network attachment definition %v", err)
}
return nil
}

func removeNetwork(client *dynClientSet, name, namespace string) error {
clusterNetwork, err := client.Networks().Get(context.Background(), "cluster", metav1.GetOptions{})
if err != nil {
return fmt.Errorf("Failed to get cluster network %v", err)
}

newClusterNetwork := clusterNetwork.DeepCopy()

spec, ok := newClusterNetwork.Object["spec"].(map[string]interface{})
if !ok {
return fmt.Errorf("Failed to fetch spec for cluster network")
}

networks, ok := (spec["additionalNetworks"]).([]interface{})
if !ok {
return fmt.Errorf("Failed to fetch additionalNetworks for cluster network %T", spec["additionalNetworks"])
}

for idx, n := range networks {
network, ok := n.(map[string]interface{})
if !ok {
return fmt.Errorf("Failed to convert network to map")
}
if network["name"] == name && network["namespace"] == namespace {
networks = append(networks[:idx], networks[idx+1:]...)
break
}
}

spec["additionalNetworks"] = networks
newClusterNetwork.Object["spec"] = spec

_, err = client.Networks().Update(context.Background(), newClusterNetwork, metav1.UpdateOptions{})
if err != nil {
return fmt.Errorf("Failed to update cluster network %v", err)
}
err = waitForNetworkAttachmentDefinitionDeleted(client, name, namespace)
if err != nil {
return fmt.Errorf("Failed to waiting for network attachment deletion %v", err)
}

return nil
}

func waitForNetworkAttachmentDefinition(client *dynClientSet, name, namespace string) error {
return wait.Poll(5*time.Second, 2*time.Minute,
func() (bool, error) {
_, err := client.NetworkAttachmentDefinitions(namespace).Get(context.Background(), name, metav1.GetOptions{})
if err != nil && errors.IsNotFound(err) {
return false, nil
}
if err != nil {
return false, err
}
return true, nil
})
}

func waitForNetworkAttachmentDefinitionDeleted(client *dynClientSet, name, namespace string) error {
return wait.Poll(5*time.Second, 2*time.Minute,
func() (bool, error) {
_, err := client.NetworkAttachmentDefinitions(namespace).Get(context.Background(), name, metav1.GetOptions{})
if err != nil && errors.IsNotFound(err) {
return true, nil
}
if err != nil {
return false, err
}
return false, nil
})
}

func newMacVlan(name, namespace string) map[string]interface{} {
return map[string]interface{}{
"name": name,
"namespace": namespace,
"type": "SimpleMacvlan",
"simpleMacvlanConfig": map[string]interface{}{
"ipamConfig": map[string]interface{}{
"type": "static",
"staticIPAMConfig": map[string]interface{}{
"addresses": []map[string]interface{}{
map[string]interface{}{
"address": "10.1.1.0/24",
},
},
},
},
},
}
}

0 comments on commit bfb978d

Please sign in to comment.