From 3399834a1f6ae8b00801649b6670c64fdb1b99a3 Mon Sep 17 00:00:00 2001 From: Joe Talerico aka rook Date: Mon, 26 Aug 2024 14:31:31 -0400 Subject: [PATCH 01/19] Enable virt Working to enable kubevirt Signed-off-by: Joe Talerico aka rook --- cmd/k8s-netperf/k8s-netperf.go | 15 ++++++ pkg/k8s/kubernetes.go | 83 ++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+) diff --git a/cmd/k8s-netperf/k8s-netperf.go b/cmd/k8s-netperf/k8s-netperf.go index 0ce0f6e8..a8a4ebca 100644 --- a/cmd/k8s-netperf/k8s-netperf.go +++ b/cmd/k8s-netperf/k8s-netperf.go @@ -23,6 +23,7 @@ import ( "github.com/google/uuid" "github.com/spf13/cobra" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" ) @@ -39,6 +40,7 @@ var ( uperf bool acrossAZ bool full bool + vm bool debug bool promURL string id string @@ -102,6 +104,10 @@ var rootCmd = &cobra.Command{ if err != nil { log.Fatal(err) } + dynClient, err := dynamic.NewForConfig(rconfig) + if err != nil { + log.Fatal(err) + } client, err := kubernetes.NewForConfig(rconfig) if err != nil { log.Fatal(err) @@ -147,6 +153,14 @@ var rootCmd = &cobra.Command{ os.Exit(1) } + if vm { + err := k8s.CreateVM(dynClient, "netperf", "client-vm") + if err != nil { + log.Error(err) + } + os.Exit(1) + } + // Build the SUT (Deployments) err = k8s.BuildSUT(client, &s) if err != nil { @@ -412,6 +426,7 @@ func main() { rootCmd.Flags().BoolVar(&clean, "clean", true, "Clean-up resources created by k8s-netperf") rootCmd.Flags().BoolVar(&json, "json", false, "Instead of human-readable output, return JSON to stdout") rootCmd.Flags().BoolVar(&nl, "local", false, "Run network performance tests with Server-Pods/Client-Pods on the same Node") + rootCmd.Flags().BoolVar(&vm, "vm", false, "Launch Virtual Machines instead of pods for client/servers") rootCmd.Flags().BoolVar(&acrossAZ, "across", false, "Place the client and server across availability zones") rootCmd.Flags().BoolVar(&full, "all", false, "Run all tests scenarios - hostNet and podNetwork (if possible)") rootCmd.Flags().BoolVar(&debug, "debug", false, "Enable debug log") diff --git a/pkg/k8s/kubernetes.go b/pkg/k8s/kubernetes.go index 024c7f4f..622d7281 100644 --- a/pkg/k8s/kubernetes.go +++ b/pkg/k8s/kubernetes.go @@ -11,8 +11,11 @@ import ( corev1 "k8s.io/api/core/v1" v1 "k8s.io/api/rbac/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes" "k8s.io/utils/pointer" ) @@ -412,6 +415,86 @@ func BuildSUT(client *kubernetes.Clientset, s *config.PerfScenarios) error { return nil } +func CreateVM(dynamicClient dynamic.Interface, namespace, vmName string) error { + gvr := schema.GroupVersionResource{ + Group: "kubevirt.io", + Version: "v1", + Resource: "virtualmachines", + } + + vm := &unstructured.Unstructured{ + Object: map[string]interface{}{ + "apiVersion": "kubevirt.io/v1", + "kind": "VirtualMachine", + "metadata": map[string]interface{}{ + "name": vmName, + "namespace": namespace, + }, + "spec": map[string]interface{}{ + "running": true, + "template": map[string]interface{}{ + "metadata": map[string]interface{}{ + "labels": map[string]interface{}{ + "kubevirt.io/domain": vmName, + }, + }, + "spec": map[string]interface{}{ + "domain": map[string]interface{}{ + "cpu": map[string]interface{}{ + "sockets": 2, + "cores": 2, + "threads": 1, + }, + "devices": map[string]interface{}{ + "disks": []interface{}{ + map[string]interface{}{ + "name": "disk0", + "disk": map[string]interface{}{ + "bus": "virtio", + }, + }, + }, + }, + "resources": map[string]interface{}{ + "requests": map[string]interface{}{ + "memory": "4096Mi", + "cpu": "500m", + }, + }, + }, + "volumes": []interface{}{ + map[string]interface{}{ + "name": "disk0", + "containerDisk": map[string]interface{}{ + "image": "kubevirt/fedora-cloud-container-disk-demo:latest", + }, + }, + map[string]interface{}{ + "name": "cloudinit", + "cloudInitNoCloud": map[string]interface{}{ + "userData": `#cloud-config + password: fedora + chpasswd: { expire: False } + runcmd: + - dnf install -y uperf iperf3 git ethtool`, + }, + }, + }, + }, + }, + }, + }, + } + + _, err := dynamicClient.Resource(gvr).Namespace(namespace).Create(context.TODO(), vm, metav1.CreateOptions{}) + if err != nil { + return fmt.Errorf("failed to create VirtualMachine: %v", err) + } + + fmt.Printf("VirtualMachine %s created successfully in namespace %s\n", vmName, namespace) + return nil +} + func zoneNodeSelectorExpression(zone string) []corev1.PreferredSchedulingTerm { return []corev1.PreferredSchedulingTerm{ { From 585c02085800954b1b9ef0293c182945307e8853 Mon Sep 17 00:00:00 2001 From: Joe Talerico aka rook Date: Tue, 27 Aug 2024 20:49:43 -0400 Subject: [PATCH 02/19] Trying the generated kubevirt client Signed-off-by: Joe Talerico aka rook --- cmd/k8s-netperf/k8s-netperf.go | 54 ++++- go.mod | 12 +- go.sum | 229 +++++++++++++++++- .../clientset/versioned/clientset.go | 118 +++++++++ .../versioned/fake/clientset_generated.go | 83 +++++++ .../client-go/clientset/versioned/fake/doc.go | 18 ++ .../clientset/versioned/fake/register.go | 54 +++++ .../clientset/versioned/scheme/doc.go | 18 ++ .../clientset/versioned/scheme/register.go | 54 +++++ .../versioned/typed/core/v1/core_client.go | 130 ++++++++++ .../clientset/versioned/typed/core/v1/doc.go | 18 ++ .../versioned/typed/core/v1/fake/doc.go | 18 ++ .../typed/core/v1/fake/fake_core_client.go | 58 +++++ .../typed/core/v1/fake/fake_kubevirt.go | 139 +++++++++++ .../typed/core/v1/fake/fake_virtualmachine.go | 139 +++++++++++ .../v1/fake/fake_virtualmachineinstance.go | 139 +++++++++++ .../fake_virtualmachineinstancemigration.go | 139 +++++++++++ .../fake/fake_virtualmachineinstancepreset.go | 127 ++++++++++ .../fake_virtualmachineinstancereplicaset.go | 139 +++++++++++ .../typed/core/v1/generated_expansion.go | 29 +++ .../versioned/typed/core/v1/kubevirt.go | 193 +++++++++++++++ .../versioned/typed/core/v1/virtualmachine.go | 193 +++++++++++++++ .../typed/core/v1/virtualmachineinstance.go | 193 +++++++++++++++ .../v1/virtualmachineinstancemigration.go | 193 +++++++++++++++ .../core/v1/virtualmachineinstancepreset.go | 176 ++++++++++++++ .../v1/virtualmachineinstancereplicaset.go | 193 +++++++++++++++ 26 files changed, 2846 insertions(+), 10 deletions(-) create mode 100644 pkg/kubevirt/client-go/clientset/versioned/clientset.go create mode 100644 pkg/kubevirt/client-go/clientset/versioned/fake/clientset_generated.go create mode 100644 pkg/kubevirt/client-go/clientset/versioned/fake/doc.go create mode 100644 pkg/kubevirt/client-go/clientset/versioned/fake/register.go create mode 100644 pkg/kubevirt/client-go/clientset/versioned/scheme/doc.go create mode 100644 pkg/kubevirt/client-go/clientset/versioned/scheme/register.go create mode 100644 pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/core_client.go create mode 100644 pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/doc.go create mode 100644 pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/fake/doc.go create mode 100644 pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/fake/fake_core_client.go create mode 100644 pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/fake/fake_kubevirt.go create mode 100644 pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/fake/fake_virtualmachine.go create mode 100644 pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/fake/fake_virtualmachineinstance.go create mode 100644 pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/fake/fake_virtualmachineinstancemigration.go create mode 100644 pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/fake/fake_virtualmachineinstancepreset.go create mode 100644 pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/fake/fake_virtualmachineinstancereplicaset.go create mode 100644 pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/generated_expansion.go create mode 100644 pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/kubevirt.go create mode 100644 pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/virtualmachine.go create mode 100644 pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/virtualmachineinstance.go create mode 100644 pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/virtualmachineinstancemigration.go create mode 100644 pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/virtualmachineinstancepreset.go create mode 100644 pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/virtualmachineinstancereplicaset.go diff --git a/cmd/k8s-netperf/k8s-netperf.go b/cmd/k8s-netperf/k8s-netperf.go index a8a4ebca..16def9e6 100644 --- a/cmd/k8s-netperf/k8s-netperf.go +++ b/cmd/k8s-netperf/k8s-netperf.go @@ -16,6 +16,7 @@ import ( "github.com/cloud-bulldozer/k8s-netperf/pkg/config" "github.com/cloud-bulldozer/k8s-netperf/pkg/drivers" "github.com/cloud-bulldozer/k8s-netperf/pkg/k8s" + kubevirtv1 "github.com/cloud-bulldozer/k8s-netperf/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1" log "github.com/cloud-bulldozer/k8s-netperf/pkg/logging" "github.com/cloud-bulldozer/k8s-netperf/pkg/metrics" result "github.com/cloud-bulldozer/k8s-netperf/pkg/results" @@ -23,9 +24,9 @@ import ( "github.com/google/uuid" "github.com/spf13/cobra" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" + v1 "kubevirt.io/api/core/v1" ) const index = "k8s-netperf" @@ -104,10 +105,6 @@ var rootCmd = &cobra.Command{ if err != nil { log.Fatal(err) } - dynClient, err := dynamic.NewForConfig(rconfig) - if err != nil { - log.Fatal(err) - } client, err := kubernetes.NewForConfig(rconfig) if err != nil { log.Fatal(err) @@ -154,10 +151,55 @@ var rootCmd = &cobra.Command{ } if vm { - err := k8s.CreateVM(dynClient, "netperf", "client-vm") + kclient, err := kubevirtv1.NewForConfig(rconfig) if err != nil { log.Error(err) } + kclient.VirtualMachineInstances("netperf").Create(context.TODO(), &v1.VirtualMachineInstance{ + Spec: v1.VirtualMachineInstanceSpec{ + Domain: v1.DomainSpec{ + CPU: &v1.CPU{ + Sockets: 2, + Cores: 2, + Threads: 1, + }, + Devices: v1.Devices{ + Disks: []v1.Disk{ + v1.Disk{ + Name: "disk0", + DiskDevice: v1.DiskDevice{ + Disk: &v1.DiskTarget{ + Bus: "virtio", + }, + }, + }, + }, + }, + }, + Volumes: []v1.Volume{ + v1.Volume{ + Name: "disk0", + VolumeSource: v1.VolumeSource{ + ContainerDisk: &v1.ContainerDiskSource{ + Image: "kubevirt/fedora-cloud-container-disk-demo:latest", + }, + }, + }, + v1.Volume{ + Name: "cloudinit", + VolumeSource: v1.VolumeSource{ + CloudInitNoCloud: &v1.CloudInitNoCloudSource{ + UserData: `#cloud-config + password: fedora + chpasswd: { expire: False } + runcmd: + - dnf install -y uperf iperf3 git ethtool`, + }, + }, + }, + }, + }, + }, metav1.CreateOptions{}) os.Exit(1) } diff --git a/go.mod b/go.mod index 2030ec2b..d9764757 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/cloud-bulldozer/k8s-netperf -go 1.18 +go 1.23 require ( github.com/aclements/go-moremath v0.0.0-20210112150236-f10218a38794 @@ -16,13 +16,15 @@ require ( k8s.io/api v0.28.4 k8s.io/apimachinery v0.28.4 k8s.io/client-go v0.28.4 - k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 + k8s.io/utils v0.0.0-20230505201702-9f6742963106 + kubevirt.io/api v1.2.2 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/elastic/go-elasticsearch/v7 v7.13.1 // indirect github.com/emicklei/go-restful/v3 v3.9.0 // indirect + github.com/evanphx/json-patch v4.12.0+incompatible // indirect github.com/go-logr/logr v1.2.4 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect @@ -43,6 +45,9 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/opensearch-project/opensearch-go v1.1.0 // indirect + github.com/openshift/api v0.0.0-20230503133300-8bbcb7ca7183 // indirect + github.com/openshift/custom-resource-status v1.1.2 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/prometheus/client_golang v1.15.1 // indirect github.com/spf13/pflag v1.0.5 // indirect golang.org/x/net v0.17.0 // indirect @@ -54,8 +59,11 @@ require ( google.golang.org/protobuf v1.31.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect + k8s.io/apiextensions-apiserver v0.26.3 // indirect k8s.io/klog/v2 v2.100.1 // indirect k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect + kubevirt.io/containerized-data-importer-api v1.57.0-alpha1 // indirect + kubevirt.io/controller-lifecycle-operator-sdk/api v0.0.0-20220329064328-f3cc58c6ed90 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect sigs.k8s.io/yaml v1.3.0 // indirect diff --git a/go.sum b/go.sum index cdac3522..0b48fb8e 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,23 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/aclements/go-moremath v0.0.0-20210112150236-f10218a38794 h1:xlwdaKcTNVW4PtpQb8aKA4Pjy0CdJHEqvFbAnvR5m2g= github.com/aclements/go-moremath v0.0.0-20210112150236-f10218a38794/go.mod h1:7e+I0LQFUI9AXWxOfsQROs9xPhoJtbsyWcjJqDd4KPY= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/aws/aws-sdk-go v1.42.27/go.mod h1:OGr6lGMAKGlG9CVrYnWYDKIyb829c6EVBRjxqjmPepc= 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/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloud-bulldozer/go-commons v1.0.16 h1:eVjOyFl7RVH3oQni0ssNT6Zjl7iovG6km11YZM1H8Ww= github.com/cloud-bulldozer/go-commons v1.0.16/go.mod h1:GF5G/9qiKJqUYIsqPgW5gFXzeSYjZn0tTScj7E/6ka4= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= @@ -11,38 +25,89 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/elastic/go-elasticsearch/v7 v7.13.1 h1:PaM3V69wPlnwR+ne50rSKKn0RNDYnnOFQcuGEI0ce80= github.com/elastic/go-elasticsearch/v7 v7.13.1/go.mod h1:OJ4wdbtDNk5g503kvlHLyErCgQwwzmDtaFC4XyOxXA4= +github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= +github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/emicklei/go-restful v2.15.0+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE= github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= +github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= +github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= +github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= +github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= +github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= +github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc= @@ -52,146 +117,306 @@ github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfC github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= +github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/montanaflynn/stats v0.6.6 h1:Duep6KMIDpY4Yo11iFsvyqJDyfzLF9+sndUKT+v64GQ= github.com/montanaflynn/stats v0.6.6/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= +github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= +github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/ginkgo/v2 v2.9.4 h1:xR7vG4IXt5RWx6FfIjyAtsoMAtnc3C/rFXBBd2AjZwE= +github.com/onsi/ginkgo/v2 v2.9.4/go.mod h1:gCQYp2Q+kSoIj7ykSVb9nskRSsR6PUj4AiLywzIhbKM= +github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= +github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= github.com/opensearch-project/opensearch-go v1.1.0 h1:eG5sh3843bbU1itPRjA9QXbxcg8LaZ+DjEzQH9aLN3M= github.com/opensearch-project/opensearch-go v1.1.0/go.mod h1:+6/XHCuTH+fwsMJikZEWsucZ4eZMma3zNSeLrTtVGbo= +github.com/openshift/api v0.0.0-20230503133300-8bbcb7ca7183 h1:t/CahSnpqY46sQR01SoS+Jt0jtjgmhgE6lFmRnO4q70= +github.com/openshift/api v0.0.0-20230503133300-8bbcb7ca7183/go.mod h1:4VWG+W22wrB4HfBL88P40DxLEpSOaiBVxUnfalfJo9k= +github.com/openshift/custom-resource-status v1.1.2 h1:C3DL44LEbvlbItfd8mT5jWrqPfHnSOQoQf/sypqA6A4= +github.com/openshift/custom-resource-status v1.1.2/go.mod h1:DB/Mf2oTeiAmVVX1gN+NEqweonAPY0TKUwADizj8+ZA= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v1.15.1 h1:8tXpTmJbyH5lydzFPoxSIJ0J46jdh3tylbvM1xCv0LI= github.com/prometheus/client_golang v1.15.1/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= +github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= +github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 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.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8= golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 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.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 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-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.6-0.20210820212750-d4cc65f0b2ff/go.mod h1:YD9qOF0M9xpSpdWTBbzEl5e/RnCefISl8E5Noe10jFM= +golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y= +golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= 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= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= 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.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/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.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +k8s.io/api v0.23.3/go.mod h1:w258XdGyvCmnBj/vGzQMj6kzdufJZVUwEM1U2fRJwSQ= k8s.io/api v0.28.4 h1:8ZBrLjwosLl/NYgv1P7EQLqoO8MGQApnbgH8tu3BMzY= k8s.io/api v0.28.4/go.mod h1:axWTGrY88s/5YE+JSt4uUi6NMM+gur1en2REMR7IRj0= +k8s.io/apiextensions-apiserver v0.26.3 h1:5PGMm3oEzdB1W/FTMgGIDmm100vn7IaUP5er36dB+YE= +k8s.io/apiextensions-apiserver v0.26.3/go.mod h1:jdA5MdjNWGP+njw1EKMZc64xAT5fIhN6VJrElV3sfpQ= +k8s.io/apimachinery v0.23.3/go.mod h1:BEuFMMBaIbcOqVIJqNZJXGFTP4W6AycEpb5+m/97hrM= k8s.io/apimachinery v0.28.4 h1:zOSJe1mc+GxuMnFzD4Z/U1wst50X28ZNsn5bhgIIao8= k8s.io/apimachinery v0.28.4/go.mod h1:wI37ncBvfAoswfq626yPTe6Bz1c22L7uaJ8dho83mgg= k8s.io/client-go v0.28.4 h1:Np5ocjlZcTrkyRJ3+T3PkXDpe4UpatQxj85+xjaD2wY= k8s.io/client-go v0.28.4/go.mod h1:0VDZFpgoZfelyP5Wqu0/r/TRYcLYuJ2U1KEeoaPa1N4= +k8s.io/code-generator v0.23.3/go.mod h1:S0Q1JVA+kSzTI1oUvbKAxZY/DYbA/ZUb4Uknog12ETk= +k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= +k8s.io/gengo v0.0.0-20211129171323-c02415ce4185/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= +k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= +k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= +k8s.io/klog/v2 v2.30.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/klog/v2 v2.40.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65/go.mod h1:sX9MT8g7NVZM5lVL/j8QyCCJe8YSMW30QvGZWaCIDIk= +k8s.io/kube-openapi v0.0.0-20220124234850-424119656bbf/go.mod h1:sX9MT8g7NVZM5lVL/j8QyCCJe8YSMW30QvGZWaCIDIk= k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ= k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM= -k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 h1:qY1Ad8PODbnymg2pRbkyMT/ylpTrCM8P2RJ0yroCyIk= -k8s.io/utils v0.0.0-20230406110748-d93618cff8a2/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20211116205334-6203023598ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20230505201702-9f6742963106 h1:EObNQ3TW2D+WptiYXlApGNLVy0zm/JIBVY9i+M4wpAU= +k8s.io/utils v0.0.0-20230505201702-9f6742963106/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +kubevirt.io/api v1.2.2 h1:PeA937vsZawmKAsiiDQZJ/BbGH4OhEWsIzWrCNfmYXk= +kubevirt.io/api v1.2.2/go.mod h1:SbeR9ma4EwnaOZEUkh/lNz0kzYm5LPpEDE30vKXC5Zg= +kubevirt.io/containerized-data-importer-api v1.57.0-alpha1 h1:IWo12+ei3jltSN5jQN1xjgakfvRSF3G3Rr4GXVOOy2I= +kubevirt.io/containerized-data-importer-api v1.57.0-alpha1/go.mod h1:Y/8ETgHS1GjO89bl682DPtQOYEU/1ctPFBz6Sjxm4DM= +kubevirt.io/controller-lifecycle-operator-sdk/api v0.0.0-20220329064328-f3cc58c6ed90 h1:QMrd0nKP0BGbnxTqakhDZAUhGKxPiPiN5gSDqKUmGGc= +kubevirt.io/controller-lifecycle-operator-sdk/api v0.0.0-20220329064328-f3cc58c6ed90/go.mod h1:018lASpFYBsYN6XwmA2TIrPCx6e0gviTd/ZNtSitKgc= +sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6/go.mod h1:p4QtZmO4uMYipTQNzagwnNoseA6OxSUutVw05NhYDRs= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= +sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= +sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= +sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= diff --git a/pkg/kubevirt/client-go/clientset/versioned/clientset.go b/pkg/kubevirt/client-go/clientset/versioned/clientset.go new file mode 100644 index 00000000..b277c2aa --- /dev/null +++ b/pkg/kubevirt/client-go/clientset/versioned/clientset.go @@ -0,0 +1,118 @@ +/* +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package versioned + +import ( + "fmt" + "net/http" + + kubevirtv1 "github.com/cloud-bulldozer/k8s-netperf/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1" + discovery "k8s.io/client-go/discovery" + rest "k8s.io/client-go/rest" + flowcontrol "k8s.io/client-go/util/flowcontrol" +) + +type Interface interface { + Discovery() discovery.DiscoveryInterface + KubevirtV1() kubevirtv1.KubevirtV1Interface +} + +// Clientset contains the clients for groups. +type Clientset struct { + *discovery.DiscoveryClient + kubevirtV1 *kubevirtv1.KubevirtV1Client +} + +// KubevirtV1 retrieves the KubevirtV1Client +func (c *Clientset) KubevirtV1() kubevirtv1.KubevirtV1Interface { + return c.kubevirtV1 +} + +// Discovery retrieves the DiscoveryClient +func (c *Clientset) Discovery() discovery.DiscoveryInterface { + if c == nil { + return nil + } + return c.DiscoveryClient +} + +// NewForConfig creates a new Clientset for the given config. +// If config's RateLimiter is not set and QPS and Burst are acceptable, +// NewForConfig will generate a rate-limiter in configShallowCopy. +// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), +// where httpClient was generated with rest.HTTPClientFor(c). +func NewForConfig(c *rest.Config) (*Clientset, error) { + configShallowCopy := *c + + if configShallowCopy.UserAgent == "" { + configShallowCopy.UserAgent = rest.DefaultKubernetesUserAgent() + } + + // share the transport between all clients + httpClient, err := rest.HTTPClientFor(&configShallowCopy) + if err != nil { + return nil, err + } + + return NewForConfigAndClient(&configShallowCopy, httpClient) +} + +// NewForConfigAndClient creates a new Clientset for the given config and http client. +// Note the http client provided takes precedence over the configured transport values. +// If config's RateLimiter is not set and QPS and Burst are acceptable, +// NewForConfigAndClient will generate a rate-limiter in configShallowCopy. +func NewForConfigAndClient(c *rest.Config, httpClient *http.Client) (*Clientset, error) { + configShallowCopy := *c + if configShallowCopy.RateLimiter == nil && configShallowCopy.QPS > 0 { + if configShallowCopy.Burst <= 0 { + return nil, fmt.Errorf("burst is required to be greater than 0 when RateLimiter is not set and QPS is set to greater than 0") + } + configShallowCopy.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(configShallowCopy.QPS, configShallowCopy.Burst) + } + + var cs Clientset + var err error + cs.kubevirtV1, err = kubevirtv1.NewForConfigAndClient(&configShallowCopy, httpClient) + if err != nil { + return nil, err + } + + cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfigAndClient(&configShallowCopy, httpClient) + if err != nil { + return nil, err + } + return &cs, nil +} + +// NewForConfigOrDie creates a new Clientset for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *Clientset { + cs, err := NewForConfig(c) + if err != nil { + panic(err) + } + return cs +} + +// New creates a new Clientset for the given RESTClient. +func New(c rest.Interface) *Clientset { + var cs Clientset + cs.kubevirtV1 = kubevirtv1.New(c) + + cs.DiscoveryClient = discovery.NewDiscoveryClient(c) + return &cs +} diff --git a/pkg/kubevirt/client-go/clientset/versioned/fake/clientset_generated.go b/pkg/kubevirt/client-go/clientset/versioned/fake/clientset_generated.go new file mode 100644 index 00000000..d29acb14 --- /dev/null +++ b/pkg/kubevirt/client-go/clientset/versioned/fake/clientset_generated.go @@ -0,0 +1,83 @@ +/* +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + clientset "github.com/cloud-bulldozer/k8s-netperf/pkg/kubevirt/client-go/clientset/versioned" + kubevirtv1 "github.com/cloud-bulldozer/k8s-netperf/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1" + fakekubevirtv1 "github.com/cloud-bulldozer/k8s-netperf/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/fake" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/discovery" + fakediscovery "k8s.io/client-go/discovery/fake" + "k8s.io/client-go/testing" +) + +// NewSimpleClientset returns a clientset that will respond with the provided objects. +// It's backed by a very simple object tracker that processes creates, updates and deletions as-is, +// without applying any validations and/or defaults. It shouldn't be considered a replacement +// for a real clientset and is mostly useful in simple unit tests. +func NewSimpleClientset(objects ...runtime.Object) *Clientset { + o := testing.NewObjectTracker(scheme, codecs.UniversalDecoder()) + for _, obj := range objects { + if err := o.Add(obj); err != nil { + panic(err) + } + } + + cs := &Clientset{tracker: o} + cs.discovery = &fakediscovery.FakeDiscovery{Fake: &cs.Fake} + cs.AddReactor("*", "*", testing.ObjectReaction(o)) + cs.AddWatchReactor("*", func(action testing.Action) (handled bool, ret watch.Interface, err error) { + gvr := action.GetResource() + ns := action.GetNamespace() + watch, err := o.Watch(gvr, ns) + if err != nil { + return false, nil, err + } + return true, watch, nil + }) + + return cs +} + +// Clientset implements clientset.Interface. Meant to be embedded into a +// struct to get a default implementation. This makes faking out just the method +// you want to test easier. +type Clientset struct { + testing.Fake + discovery *fakediscovery.FakeDiscovery + tracker testing.ObjectTracker +} + +func (c *Clientset) Discovery() discovery.DiscoveryInterface { + return c.discovery +} + +func (c *Clientset) Tracker() testing.ObjectTracker { + return c.tracker +} + +var ( + _ clientset.Interface = &Clientset{} + _ testing.FakeClient = &Clientset{} +) + +// KubevirtV1 retrieves the KubevirtV1Client +func (c *Clientset) KubevirtV1() kubevirtv1.KubevirtV1Interface { + return &fakekubevirtv1.FakeKubevirtV1{Fake: &c.Fake} +} diff --git a/pkg/kubevirt/client-go/clientset/versioned/fake/doc.go b/pkg/kubevirt/client-go/clientset/versioned/fake/doc.go new file mode 100644 index 00000000..8c0e7424 --- /dev/null +++ b/pkg/kubevirt/client-go/clientset/versioned/fake/doc.go @@ -0,0 +1,18 @@ +/* +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// This package has the automatically generated fake clientset. +package fake diff --git a/pkg/kubevirt/client-go/clientset/versioned/fake/register.go b/pkg/kubevirt/client-go/clientset/versioned/fake/register.go new file mode 100644 index 00000000..70c3d177 --- /dev/null +++ b/pkg/kubevirt/client-go/clientset/versioned/fake/register.go @@ -0,0 +1,54 @@ +/* +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" + serializer "k8s.io/apimachinery/pkg/runtime/serializer" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + kubevirtv1 "kubevirt.io/api/core/v1" +) + +var scheme = runtime.NewScheme() +var codecs = serializer.NewCodecFactory(scheme) + +var localSchemeBuilder = runtime.SchemeBuilder{ + kubevirtv1.AddToScheme, +} + +// AddToScheme adds all types of this clientset into the given scheme. This allows composition +// of clientsets, like in: +// +// import ( +// "k8s.io/client-go/kubernetes" +// clientsetscheme "k8s.io/client-go/kubernetes/scheme" +// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" +// ) +// +// kclientset, _ := kubernetes.NewForConfig(c) +// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) +// +// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types +// correctly. +var AddToScheme = localSchemeBuilder.AddToScheme + +func init() { + v1.AddToGroupVersion(scheme, schema.GroupVersion{Version: "v1"}) + utilruntime.Must(AddToScheme(scheme)) +} diff --git a/pkg/kubevirt/client-go/clientset/versioned/scheme/doc.go b/pkg/kubevirt/client-go/clientset/versioned/scheme/doc.go new file mode 100644 index 00000000..23b38d42 --- /dev/null +++ b/pkg/kubevirt/client-go/clientset/versioned/scheme/doc.go @@ -0,0 +1,18 @@ +/* +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// This package contains the scheme of the automatically generated clientset. +package scheme diff --git a/pkg/kubevirt/client-go/clientset/versioned/scheme/register.go b/pkg/kubevirt/client-go/clientset/versioned/scheme/register.go new file mode 100644 index 00000000..fc13bf6a --- /dev/null +++ b/pkg/kubevirt/client-go/clientset/versioned/scheme/register.go @@ -0,0 +1,54 @@ +/* +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package scheme + +import ( + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" + serializer "k8s.io/apimachinery/pkg/runtime/serializer" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + kubevirtv1 "kubevirt.io/api/core/v1" +) + +var Scheme = runtime.NewScheme() +var Codecs = serializer.NewCodecFactory(Scheme) +var ParameterCodec = runtime.NewParameterCodec(Scheme) +var localSchemeBuilder = runtime.SchemeBuilder{ + kubevirtv1.AddToScheme, +} + +// AddToScheme adds all types of this clientset into the given scheme. This allows composition +// of clientsets, like in: +// +// import ( +// "k8s.io/client-go/kubernetes" +// clientsetscheme "k8s.io/client-go/kubernetes/scheme" +// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" +// ) +// +// kclientset, _ := kubernetes.NewForConfig(c) +// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) +// +// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types +// correctly. +var AddToScheme = localSchemeBuilder.AddToScheme + +func init() { + v1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"}) + utilruntime.Must(AddToScheme(Scheme)) +} diff --git a/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/core_client.go b/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/core_client.go new file mode 100644 index 00000000..10f35a5e --- /dev/null +++ b/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/core_client.go @@ -0,0 +1,130 @@ +/* +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + "net/http" + + "github.com/cloud-bulldozer/k8s-netperf/pkg/kubevirt/client-go/clientset/versioned/scheme" + rest "k8s.io/client-go/rest" + v1 "kubevirt.io/api/core/v1" +) + +type KubevirtV1Interface interface { + RESTClient() rest.Interface + KubeVirtsGetter + VirtualMachinesGetter + VirtualMachineInstancesGetter + VirtualMachineInstanceMigrationsGetter + VirtualMachineInstancePresetsGetter + VirtualMachineInstanceReplicaSetsGetter +} + +// KubevirtV1Client is used to interact with features provided by the kubevirt.io group. +type KubevirtV1Client struct { + restClient rest.Interface +} + +func (c *KubevirtV1Client) KubeVirts(namespace string) KubeVirtInterface { + return newKubeVirts(c, namespace) +} + +func (c *KubevirtV1Client) VirtualMachines(namespace string) VirtualMachineInterface { + return newVirtualMachines(c, namespace) +} + +func (c *KubevirtV1Client) VirtualMachineInstances(namespace string) VirtualMachineInstanceInterface { + return newVirtualMachineInstances(c, namespace) +} + +func (c *KubevirtV1Client) VirtualMachineInstanceMigrations(namespace string) VirtualMachineInstanceMigrationInterface { + return newVirtualMachineInstanceMigrations(c, namespace) +} + +func (c *KubevirtV1Client) VirtualMachineInstancePresets(namespace string) VirtualMachineInstancePresetInterface { + return newVirtualMachineInstancePresets(c, namespace) +} + +func (c *KubevirtV1Client) VirtualMachineInstanceReplicaSets(namespace string) VirtualMachineInstanceReplicaSetInterface { + return newVirtualMachineInstanceReplicaSets(c, namespace) +} + +// NewForConfig creates a new KubevirtV1Client for the given config. +// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), +// where httpClient was generated with rest.HTTPClientFor(c). +func NewForConfig(c *rest.Config) (*KubevirtV1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + httpClient, err := rest.HTTPClientFor(&config) + if err != nil { + return nil, err + } + return NewForConfigAndClient(&config, httpClient) +} + +// NewForConfigAndClient creates a new KubevirtV1Client for the given config and http client. +// Note the http client provided takes precedence over the configured transport values. +func NewForConfigAndClient(c *rest.Config, h *http.Client) (*KubevirtV1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + client, err := rest.RESTClientForConfigAndClient(&config, h) + if err != nil { + return nil, err + } + return &KubevirtV1Client{client}, nil +} + +// NewForConfigOrDie creates a new KubevirtV1Client for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *KubevirtV1Client { + client, err := NewForConfig(c) + if err != nil { + panic(err) + } + return client +} + +// New creates a new KubevirtV1Client for the given RESTClient. +func New(c rest.Interface) *KubevirtV1Client { + return &KubevirtV1Client{c} +} + +func setConfigDefaults(config *rest.Config) error { + gv := v1.SchemeGroupVersion + config.GroupVersion = &gv + config.APIPath = "/apis" + config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() + + if config.UserAgent == "" { + config.UserAgent = rest.DefaultKubernetesUserAgent() + } + + return nil +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *KubevirtV1Client) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} diff --git a/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/doc.go b/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/doc.go new file mode 100644 index 00000000..811e0ae1 --- /dev/null +++ b/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/doc.go @@ -0,0 +1,18 @@ +/* +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// This package has the automatically generated typed clients. +package v1 diff --git a/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/fake/doc.go b/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/fake/doc.go new file mode 100644 index 00000000..3c48772f --- /dev/null +++ b/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/fake/doc.go @@ -0,0 +1,18 @@ +/* +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// Package fake has the automatically generated clients. +package fake diff --git a/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/fake/fake_core_client.go b/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/fake/fake_core_client.go new file mode 100644 index 00000000..85c26bd3 --- /dev/null +++ b/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/fake/fake_core_client.go @@ -0,0 +1,58 @@ +/* +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1 "github.com/cloud-bulldozer/k8s-netperf/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1" + rest "k8s.io/client-go/rest" + testing "k8s.io/client-go/testing" +) + +type FakeKubevirtV1 struct { + *testing.Fake +} + +func (c *FakeKubevirtV1) KubeVirts(namespace string) v1.KubeVirtInterface { + return &FakeKubeVirts{c, namespace} +} + +func (c *FakeKubevirtV1) VirtualMachines(namespace string) v1.VirtualMachineInterface { + return &FakeVirtualMachines{c, namespace} +} + +func (c *FakeKubevirtV1) VirtualMachineInstances(namespace string) v1.VirtualMachineInstanceInterface { + return &FakeVirtualMachineInstances{c, namespace} +} + +func (c *FakeKubevirtV1) VirtualMachineInstanceMigrations(namespace string) v1.VirtualMachineInstanceMigrationInterface { + return &FakeVirtualMachineInstanceMigrations{c, namespace} +} + +func (c *FakeKubevirtV1) VirtualMachineInstancePresets(namespace string) v1.VirtualMachineInstancePresetInterface { + return &FakeVirtualMachineInstancePresets{c, namespace} +} + +func (c *FakeKubevirtV1) VirtualMachineInstanceReplicaSets(namespace string) v1.VirtualMachineInstanceReplicaSetInterface { + return &FakeVirtualMachineInstanceReplicaSets{c, namespace} +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *FakeKubevirtV1) RESTClient() rest.Interface { + var ret *rest.RESTClient + return ret +} diff --git a/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/fake/fake_kubevirt.go b/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/fake/fake_kubevirt.go new file mode 100644 index 00000000..8e6bbd9d --- /dev/null +++ b/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/fake/fake_kubevirt.go @@ -0,0 +1,139 @@ +/* +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + "context" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" + v1 "kubevirt.io/api/core/v1" +) + +// FakeKubeVirts implements KubeVirtInterface +type FakeKubeVirts struct { + Fake *FakeKubevirtV1 + ns string +} + +var kubevirtsResource = v1.SchemeGroupVersion.WithResource("kubevirts") + +var kubevirtsKind = v1.SchemeGroupVersion.WithKind("KubeVirt") + +// Get takes name of the kubeVirt, and returns the corresponding kubeVirt object, and an error if there is any. +func (c *FakeKubeVirts) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.KubeVirt, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(kubevirtsResource, c.ns, name), &v1.KubeVirt{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.KubeVirt), err +} + +// List takes label and field selectors, and returns the list of KubeVirts that match those selectors. +func (c *FakeKubeVirts) List(ctx context.Context, opts metav1.ListOptions) (result *v1.KubeVirtList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(kubevirtsResource, kubevirtsKind, c.ns, opts), &v1.KubeVirtList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1.KubeVirtList{ListMeta: obj.(*v1.KubeVirtList).ListMeta} + for _, item := range obj.(*v1.KubeVirtList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested kubeVirts. +func (c *FakeKubeVirts) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(kubevirtsResource, c.ns, opts)) + +} + +// Create takes the representation of a kubeVirt and creates it. Returns the server's representation of the kubeVirt, and an error, if there is any. +func (c *FakeKubeVirts) Create(ctx context.Context, kubeVirt *v1.KubeVirt, opts metav1.CreateOptions) (result *v1.KubeVirt, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(kubevirtsResource, c.ns, kubeVirt), &v1.KubeVirt{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.KubeVirt), err +} + +// Update takes the representation of a kubeVirt and updates it. Returns the server's representation of the kubeVirt, and an error, if there is any. +func (c *FakeKubeVirts) Update(ctx context.Context, kubeVirt *v1.KubeVirt, opts metav1.UpdateOptions) (result *v1.KubeVirt, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(kubevirtsResource, c.ns, kubeVirt), &v1.KubeVirt{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.KubeVirt), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeKubeVirts) UpdateStatus(ctx context.Context, kubeVirt *v1.KubeVirt, opts metav1.UpdateOptions) (*v1.KubeVirt, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(kubevirtsResource, "status", c.ns, kubeVirt), &v1.KubeVirt{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.KubeVirt), err +} + +// Delete takes name of the kubeVirt and deletes it. Returns an error if one occurs. +func (c *FakeKubeVirts) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(kubevirtsResource, c.ns, name, opts), &v1.KubeVirt{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeKubeVirts) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + action := testing.NewDeleteCollectionAction(kubevirtsResource, c.ns, listOpts) + + _, err := c.Fake.Invokes(action, &v1.KubeVirtList{}) + return err +} + +// Patch applies the patch and returns the patched kubeVirt. +func (c *FakeKubeVirts) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.KubeVirt, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(kubevirtsResource, c.ns, name, pt, data, subresources...), &v1.KubeVirt{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.KubeVirt), err +} diff --git a/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/fake/fake_virtualmachine.go b/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/fake/fake_virtualmachine.go new file mode 100644 index 00000000..f0232147 --- /dev/null +++ b/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/fake/fake_virtualmachine.go @@ -0,0 +1,139 @@ +/* +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + "context" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" + v1 "kubevirt.io/api/core/v1" +) + +// FakeVirtualMachines implements VirtualMachineInterface +type FakeVirtualMachines struct { + Fake *FakeKubevirtV1 + ns string +} + +var virtualmachinesResource = v1.SchemeGroupVersion.WithResource("virtualmachines") + +var virtualmachinesKind = v1.SchemeGroupVersion.WithKind("VirtualMachine") + +// Get takes name of the virtualMachine, and returns the corresponding virtualMachine object, and an error if there is any. +func (c *FakeVirtualMachines) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.VirtualMachine, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(virtualmachinesResource, c.ns, name), &v1.VirtualMachine{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.VirtualMachine), err +} + +// List takes label and field selectors, and returns the list of VirtualMachines that match those selectors. +func (c *FakeVirtualMachines) List(ctx context.Context, opts metav1.ListOptions) (result *v1.VirtualMachineList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(virtualmachinesResource, virtualmachinesKind, c.ns, opts), &v1.VirtualMachineList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1.VirtualMachineList{ListMeta: obj.(*v1.VirtualMachineList).ListMeta} + for _, item := range obj.(*v1.VirtualMachineList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested virtualMachines. +func (c *FakeVirtualMachines) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(virtualmachinesResource, c.ns, opts)) + +} + +// Create takes the representation of a virtualMachine and creates it. Returns the server's representation of the virtualMachine, and an error, if there is any. +func (c *FakeVirtualMachines) Create(ctx context.Context, virtualMachine *v1.VirtualMachine, opts metav1.CreateOptions) (result *v1.VirtualMachine, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(virtualmachinesResource, c.ns, virtualMachine), &v1.VirtualMachine{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.VirtualMachine), err +} + +// Update takes the representation of a virtualMachine and updates it. Returns the server's representation of the virtualMachine, and an error, if there is any. +func (c *FakeVirtualMachines) Update(ctx context.Context, virtualMachine *v1.VirtualMachine, opts metav1.UpdateOptions) (result *v1.VirtualMachine, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(virtualmachinesResource, c.ns, virtualMachine), &v1.VirtualMachine{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.VirtualMachine), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeVirtualMachines) UpdateStatus(ctx context.Context, virtualMachine *v1.VirtualMachine, opts metav1.UpdateOptions) (*v1.VirtualMachine, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(virtualmachinesResource, "status", c.ns, virtualMachine), &v1.VirtualMachine{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.VirtualMachine), err +} + +// Delete takes name of the virtualMachine and deletes it. Returns an error if one occurs. +func (c *FakeVirtualMachines) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(virtualmachinesResource, c.ns, name, opts), &v1.VirtualMachine{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeVirtualMachines) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + action := testing.NewDeleteCollectionAction(virtualmachinesResource, c.ns, listOpts) + + _, err := c.Fake.Invokes(action, &v1.VirtualMachineList{}) + return err +} + +// Patch applies the patch and returns the patched virtualMachine. +func (c *FakeVirtualMachines) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.VirtualMachine, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(virtualmachinesResource, c.ns, name, pt, data, subresources...), &v1.VirtualMachine{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.VirtualMachine), err +} diff --git a/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/fake/fake_virtualmachineinstance.go b/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/fake/fake_virtualmachineinstance.go new file mode 100644 index 00000000..f9c70482 --- /dev/null +++ b/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/fake/fake_virtualmachineinstance.go @@ -0,0 +1,139 @@ +/* +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + "context" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" + v1 "kubevirt.io/api/core/v1" +) + +// FakeVirtualMachineInstances implements VirtualMachineInstanceInterface +type FakeVirtualMachineInstances struct { + Fake *FakeKubevirtV1 + ns string +} + +var virtualmachineinstancesResource = v1.SchemeGroupVersion.WithResource("virtualmachineinstances") + +var virtualmachineinstancesKind = v1.SchemeGroupVersion.WithKind("VirtualMachineInstance") + +// Get takes name of the virtualMachineInstance, and returns the corresponding virtualMachineInstance object, and an error if there is any. +func (c *FakeVirtualMachineInstances) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.VirtualMachineInstance, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(virtualmachineinstancesResource, c.ns, name), &v1.VirtualMachineInstance{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.VirtualMachineInstance), err +} + +// List takes label and field selectors, and returns the list of VirtualMachineInstances that match those selectors. +func (c *FakeVirtualMachineInstances) List(ctx context.Context, opts metav1.ListOptions) (result *v1.VirtualMachineInstanceList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(virtualmachineinstancesResource, virtualmachineinstancesKind, c.ns, opts), &v1.VirtualMachineInstanceList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1.VirtualMachineInstanceList{ListMeta: obj.(*v1.VirtualMachineInstanceList).ListMeta} + for _, item := range obj.(*v1.VirtualMachineInstanceList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested virtualMachineInstances. +func (c *FakeVirtualMachineInstances) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(virtualmachineinstancesResource, c.ns, opts)) + +} + +// Create takes the representation of a virtualMachineInstance and creates it. Returns the server's representation of the virtualMachineInstance, and an error, if there is any. +func (c *FakeVirtualMachineInstances) Create(ctx context.Context, virtualMachineInstance *v1.VirtualMachineInstance, opts metav1.CreateOptions) (result *v1.VirtualMachineInstance, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(virtualmachineinstancesResource, c.ns, virtualMachineInstance), &v1.VirtualMachineInstance{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.VirtualMachineInstance), err +} + +// Update takes the representation of a virtualMachineInstance and updates it. Returns the server's representation of the virtualMachineInstance, and an error, if there is any. +func (c *FakeVirtualMachineInstances) Update(ctx context.Context, virtualMachineInstance *v1.VirtualMachineInstance, opts metav1.UpdateOptions) (result *v1.VirtualMachineInstance, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(virtualmachineinstancesResource, c.ns, virtualMachineInstance), &v1.VirtualMachineInstance{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.VirtualMachineInstance), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeVirtualMachineInstances) UpdateStatus(ctx context.Context, virtualMachineInstance *v1.VirtualMachineInstance, opts metav1.UpdateOptions) (*v1.VirtualMachineInstance, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(virtualmachineinstancesResource, "status", c.ns, virtualMachineInstance), &v1.VirtualMachineInstance{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.VirtualMachineInstance), err +} + +// Delete takes name of the virtualMachineInstance and deletes it. Returns an error if one occurs. +func (c *FakeVirtualMachineInstances) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(virtualmachineinstancesResource, c.ns, name, opts), &v1.VirtualMachineInstance{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeVirtualMachineInstances) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + action := testing.NewDeleteCollectionAction(virtualmachineinstancesResource, c.ns, listOpts) + + _, err := c.Fake.Invokes(action, &v1.VirtualMachineInstanceList{}) + return err +} + +// Patch applies the patch and returns the patched virtualMachineInstance. +func (c *FakeVirtualMachineInstances) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.VirtualMachineInstance, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(virtualmachineinstancesResource, c.ns, name, pt, data, subresources...), &v1.VirtualMachineInstance{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.VirtualMachineInstance), err +} diff --git a/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/fake/fake_virtualmachineinstancemigration.go b/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/fake/fake_virtualmachineinstancemigration.go new file mode 100644 index 00000000..f38e5d7c --- /dev/null +++ b/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/fake/fake_virtualmachineinstancemigration.go @@ -0,0 +1,139 @@ +/* +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + "context" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" + v1 "kubevirt.io/api/core/v1" +) + +// FakeVirtualMachineInstanceMigrations implements VirtualMachineInstanceMigrationInterface +type FakeVirtualMachineInstanceMigrations struct { + Fake *FakeKubevirtV1 + ns string +} + +var virtualmachineinstancemigrationsResource = v1.SchemeGroupVersion.WithResource("virtualmachineinstancemigrations") + +var virtualmachineinstancemigrationsKind = v1.SchemeGroupVersion.WithKind("VirtualMachineInstanceMigration") + +// Get takes name of the virtualMachineInstanceMigration, and returns the corresponding virtualMachineInstanceMigration object, and an error if there is any. +func (c *FakeVirtualMachineInstanceMigrations) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.VirtualMachineInstanceMigration, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(virtualmachineinstancemigrationsResource, c.ns, name), &v1.VirtualMachineInstanceMigration{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.VirtualMachineInstanceMigration), err +} + +// List takes label and field selectors, and returns the list of VirtualMachineInstanceMigrations that match those selectors. +func (c *FakeVirtualMachineInstanceMigrations) List(ctx context.Context, opts metav1.ListOptions) (result *v1.VirtualMachineInstanceMigrationList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(virtualmachineinstancemigrationsResource, virtualmachineinstancemigrationsKind, c.ns, opts), &v1.VirtualMachineInstanceMigrationList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1.VirtualMachineInstanceMigrationList{ListMeta: obj.(*v1.VirtualMachineInstanceMigrationList).ListMeta} + for _, item := range obj.(*v1.VirtualMachineInstanceMigrationList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested virtualMachineInstanceMigrations. +func (c *FakeVirtualMachineInstanceMigrations) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(virtualmachineinstancemigrationsResource, c.ns, opts)) + +} + +// Create takes the representation of a virtualMachineInstanceMigration and creates it. Returns the server's representation of the virtualMachineInstanceMigration, and an error, if there is any. +func (c *FakeVirtualMachineInstanceMigrations) Create(ctx context.Context, virtualMachineInstanceMigration *v1.VirtualMachineInstanceMigration, opts metav1.CreateOptions) (result *v1.VirtualMachineInstanceMigration, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(virtualmachineinstancemigrationsResource, c.ns, virtualMachineInstanceMigration), &v1.VirtualMachineInstanceMigration{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.VirtualMachineInstanceMigration), err +} + +// Update takes the representation of a virtualMachineInstanceMigration and updates it. Returns the server's representation of the virtualMachineInstanceMigration, and an error, if there is any. +func (c *FakeVirtualMachineInstanceMigrations) Update(ctx context.Context, virtualMachineInstanceMigration *v1.VirtualMachineInstanceMigration, opts metav1.UpdateOptions) (result *v1.VirtualMachineInstanceMigration, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(virtualmachineinstancemigrationsResource, c.ns, virtualMachineInstanceMigration), &v1.VirtualMachineInstanceMigration{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.VirtualMachineInstanceMigration), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeVirtualMachineInstanceMigrations) UpdateStatus(ctx context.Context, virtualMachineInstanceMigration *v1.VirtualMachineInstanceMigration, opts metav1.UpdateOptions) (*v1.VirtualMachineInstanceMigration, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(virtualmachineinstancemigrationsResource, "status", c.ns, virtualMachineInstanceMigration), &v1.VirtualMachineInstanceMigration{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.VirtualMachineInstanceMigration), err +} + +// Delete takes name of the virtualMachineInstanceMigration and deletes it. Returns an error if one occurs. +func (c *FakeVirtualMachineInstanceMigrations) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(virtualmachineinstancemigrationsResource, c.ns, name, opts), &v1.VirtualMachineInstanceMigration{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeVirtualMachineInstanceMigrations) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + action := testing.NewDeleteCollectionAction(virtualmachineinstancemigrationsResource, c.ns, listOpts) + + _, err := c.Fake.Invokes(action, &v1.VirtualMachineInstanceMigrationList{}) + return err +} + +// Patch applies the patch and returns the patched virtualMachineInstanceMigration. +func (c *FakeVirtualMachineInstanceMigrations) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.VirtualMachineInstanceMigration, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(virtualmachineinstancemigrationsResource, c.ns, name, pt, data, subresources...), &v1.VirtualMachineInstanceMigration{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.VirtualMachineInstanceMigration), err +} diff --git a/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/fake/fake_virtualmachineinstancepreset.go b/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/fake/fake_virtualmachineinstancepreset.go new file mode 100644 index 00000000..1bf6754f --- /dev/null +++ b/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/fake/fake_virtualmachineinstancepreset.go @@ -0,0 +1,127 @@ +/* +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + "context" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" + v1 "kubevirt.io/api/core/v1" +) + +// FakeVirtualMachineInstancePresets implements VirtualMachineInstancePresetInterface +type FakeVirtualMachineInstancePresets struct { + Fake *FakeKubevirtV1 + ns string +} + +var virtualmachineinstancepresetsResource = v1.SchemeGroupVersion.WithResource("virtualmachineinstancepresets") + +var virtualmachineinstancepresetsKind = v1.SchemeGroupVersion.WithKind("VirtualMachineInstancePreset") + +// Get takes name of the virtualMachineInstancePreset, and returns the corresponding virtualMachineInstancePreset object, and an error if there is any. +func (c *FakeVirtualMachineInstancePresets) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.VirtualMachineInstancePreset, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(virtualmachineinstancepresetsResource, c.ns, name), &v1.VirtualMachineInstancePreset{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.VirtualMachineInstancePreset), err +} + +// List takes label and field selectors, and returns the list of VirtualMachineInstancePresets that match those selectors. +func (c *FakeVirtualMachineInstancePresets) List(ctx context.Context, opts metav1.ListOptions) (result *v1.VirtualMachineInstancePresetList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(virtualmachineinstancepresetsResource, virtualmachineinstancepresetsKind, c.ns, opts), &v1.VirtualMachineInstancePresetList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1.VirtualMachineInstancePresetList{ListMeta: obj.(*v1.VirtualMachineInstancePresetList).ListMeta} + for _, item := range obj.(*v1.VirtualMachineInstancePresetList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested virtualMachineInstancePresets. +func (c *FakeVirtualMachineInstancePresets) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(virtualmachineinstancepresetsResource, c.ns, opts)) + +} + +// Create takes the representation of a virtualMachineInstancePreset and creates it. Returns the server's representation of the virtualMachineInstancePreset, and an error, if there is any. +func (c *FakeVirtualMachineInstancePresets) Create(ctx context.Context, virtualMachineInstancePreset *v1.VirtualMachineInstancePreset, opts metav1.CreateOptions) (result *v1.VirtualMachineInstancePreset, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(virtualmachineinstancepresetsResource, c.ns, virtualMachineInstancePreset), &v1.VirtualMachineInstancePreset{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.VirtualMachineInstancePreset), err +} + +// Update takes the representation of a virtualMachineInstancePreset and updates it. Returns the server's representation of the virtualMachineInstancePreset, and an error, if there is any. +func (c *FakeVirtualMachineInstancePresets) Update(ctx context.Context, virtualMachineInstancePreset *v1.VirtualMachineInstancePreset, opts metav1.UpdateOptions) (result *v1.VirtualMachineInstancePreset, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(virtualmachineinstancepresetsResource, c.ns, virtualMachineInstancePreset), &v1.VirtualMachineInstancePreset{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.VirtualMachineInstancePreset), err +} + +// Delete takes name of the virtualMachineInstancePreset and deletes it. Returns an error if one occurs. +func (c *FakeVirtualMachineInstancePresets) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(virtualmachineinstancepresetsResource, c.ns, name, opts), &v1.VirtualMachineInstancePreset{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeVirtualMachineInstancePresets) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + action := testing.NewDeleteCollectionAction(virtualmachineinstancepresetsResource, c.ns, listOpts) + + _, err := c.Fake.Invokes(action, &v1.VirtualMachineInstancePresetList{}) + return err +} + +// Patch applies the patch and returns the patched virtualMachineInstancePreset. +func (c *FakeVirtualMachineInstancePresets) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.VirtualMachineInstancePreset, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(virtualmachineinstancepresetsResource, c.ns, name, pt, data, subresources...), &v1.VirtualMachineInstancePreset{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.VirtualMachineInstancePreset), err +} diff --git a/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/fake/fake_virtualmachineinstancereplicaset.go b/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/fake/fake_virtualmachineinstancereplicaset.go new file mode 100644 index 00000000..eb59b209 --- /dev/null +++ b/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/fake/fake_virtualmachineinstancereplicaset.go @@ -0,0 +1,139 @@ +/* +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + "context" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" + v1 "kubevirt.io/api/core/v1" +) + +// FakeVirtualMachineInstanceReplicaSets implements VirtualMachineInstanceReplicaSetInterface +type FakeVirtualMachineInstanceReplicaSets struct { + Fake *FakeKubevirtV1 + ns string +} + +var virtualmachineinstancereplicasetsResource = v1.SchemeGroupVersion.WithResource("virtualmachineinstancereplicasets") + +var virtualmachineinstancereplicasetsKind = v1.SchemeGroupVersion.WithKind("VirtualMachineInstanceReplicaSet") + +// Get takes name of the virtualMachineInstanceReplicaSet, and returns the corresponding virtualMachineInstanceReplicaSet object, and an error if there is any. +func (c *FakeVirtualMachineInstanceReplicaSets) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.VirtualMachineInstanceReplicaSet, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(virtualmachineinstancereplicasetsResource, c.ns, name), &v1.VirtualMachineInstanceReplicaSet{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.VirtualMachineInstanceReplicaSet), err +} + +// List takes label and field selectors, and returns the list of VirtualMachineInstanceReplicaSets that match those selectors. +func (c *FakeVirtualMachineInstanceReplicaSets) List(ctx context.Context, opts metav1.ListOptions) (result *v1.VirtualMachineInstanceReplicaSetList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(virtualmachineinstancereplicasetsResource, virtualmachineinstancereplicasetsKind, c.ns, opts), &v1.VirtualMachineInstanceReplicaSetList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1.VirtualMachineInstanceReplicaSetList{ListMeta: obj.(*v1.VirtualMachineInstanceReplicaSetList).ListMeta} + for _, item := range obj.(*v1.VirtualMachineInstanceReplicaSetList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested virtualMachineInstanceReplicaSets. +func (c *FakeVirtualMachineInstanceReplicaSets) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(virtualmachineinstancereplicasetsResource, c.ns, opts)) + +} + +// Create takes the representation of a virtualMachineInstanceReplicaSet and creates it. Returns the server's representation of the virtualMachineInstanceReplicaSet, and an error, if there is any. +func (c *FakeVirtualMachineInstanceReplicaSets) Create(ctx context.Context, virtualMachineInstanceReplicaSet *v1.VirtualMachineInstanceReplicaSet, opts metav1.CreateOptions) (result *v1.VirtualMachineInstanceReplicaSet, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(virtualmachineinstancereplicasetsResource, c.ns, virtualMachineInstanceReplicaSet), &v1.VirtualMachineInstanceReplicaSet{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.VirtualMachineInstanceReplicaSet), err +} + +// Update takes the representation of a virtualMachineInstanceReplicaSet and updates it. Returns the server's representation of the virtualMachineInstanceReplicaSet, and an error, if there is any. +func (c *FakeVirtualMachineInstanceReplicaSets) Update(ctx context.Context, virtualMachineInstanceReplicaSet *v1.VirtualMachineInstanceReplicaSet, opts metav1.UpdateOptions) (result *v1.VirtualMachineInstanceReplicaSet, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(virtualmachineinstancereplicasetsResource, c.ns, virtualMachineInstanceReplicaSet), &v1.VirtualMachineInstanceReplicaSet{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.VirtualMachineInstanceReplicaSet), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeVirtualMachineInstanceReplicaSets) UpdateStatus(ctx context.Context, virtualMachineInstanceReplicaSet *v1.VirtualMachineInstanceReplicaSet, opts metav1.UpdateOptions) (*v1.VirtualMachineInstanceReplicaSet, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(virtualmachineinstancereplicasetsResource, "status", c.ns, virtualMachineInstanceReplicaSet), &v1.VirtualMachineInstanceReplicaSet{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.VirtualMachineInstanceReplicaSet), err +} + +// Delete takes name of the virtualMachineInstanceReplicaSet and deletes it. Returns an error if one occurs. +func (c *FakeVirtualMachineInstanceReplicaSets) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(virtualmachineinstancereplicasetsResource, c.ns, name, opts), &v1.VirtualMachineInstanceReplicaSet{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeVirtualMachineInstanceReplicaSets) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + action := testing.NewDeleteCollectionAction(virtualmachineinstancereplicasetsResource, c.ns, listOpts) + + _, err := c.Fake.Invokes(action, &v1.VirtualMachineInstanceReplicaSetList{}) + return err +} + +// Patch applies the patch and returns the patched virtualMachineInstanceReplicaSet. +func (c *FakeVirtualMachineInstanceReplicaSets) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.VirtualMachineInstanceReplicaSet, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(virtualmachineinstancereplicasetsResource, c.ns, name, pt, data, subresources...), &v1.VirtualMachineInstanceReplicaSet{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.VirtualMachineInstanceReplicaSet), err +} diff --git a/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/generated_expansion.go b/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/generated_expansion.go new file mode 100644 index 00000000..62a0c561 --- /dev/null +++ b/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/generated_expansion.go @@ -0,0 +1,29 @@ +/* +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +type KubeVirtExpansion interface{} + +type VirtualMachineExpansion interface{} + +type VirtualMachineInstanceExpansion interface{} + +type VirtualMachineInstanceMigrationExpansion interface{} + +type VirtualMachineInstancePresetExpansion interface{} + +type VirtualMachineInstanceReplicaSetExpansion interface{} diff --git a/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/kubevirt.go b/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/kubevirt.go new file mode 100644 index 00000000..8263bdda --- /dev/null +++ b/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/kubevirt.go @@ -0,0 +1,193 @@ +/* +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + scheme "github.com/cloud-bulldozer/k8s-netperf/pkg/kubevirt/client-go/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" + v1 "kubevirt.io/api/core/v1" +) + +// KubeVirtsGetter has a method to return a KubeVirtInterface. +// A group's client should implement this interface. +type KubeVirtsGetter interface { + KubeVirts(namespace string) KubeVirtInterface +} + +// KubeVirtInterface has methods to work with KubeVirt resources. +type KubeVirtInterface interface { + Create(ctx context.Context, kubeVirt *v1.KubeVirt, opts metav1.CreateOptions) (*v1.KubeVirt, error) + Update(ctx context.Context, kubeVirt *v1.KubeVirt, opts metav1.UpdateOptions) (*v1.KubeVirt, error) + UpdateStatus(ctx context.Context, kubeVirt *v1.KubeVirt, opts metav1.UpdateOptions) (*v1.KubeVirt, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.KubeVirt, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.KubeVirtList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.KubeVirt, err error) + KubeVirtExpansion +} + +// kubeVirts implements KubeVirtInterface +type kubeVirts struct { + client rest.Interface + ns string +} + +// newKubeVirts returns a KubeVirts +func newKubeVirts(c *KubevirtV1Client, namespace string) *kubeVirts { + return &kubeVirts{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the kubeVirt, and returns the corresponding kubeVirt object, and an error if there is any. +func (c *kubeVirts) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.KubeVirt, err error) { + result = &v1.KubeVirt{} + err = c.client.Get(). + Namespace(c.ns). + Resource("kubevirts"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of KubeVirts that match those selectors. +func (c *kubeVirts) List(ctx context.Context, opts metav1.ListOptions) (result *v1.KubeVirtList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.KubeVirtList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("kubevirts"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested kubeVirts. +func (c *kubeVirts) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("kubevirts"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a kubeVirt and creates it. Returns the server's representation of the kubeVirt, and an error, if there is any. +func (c *kubeVirts) Create(ctx context.Context, kubeVirt *v1.KubeVirt, opts metav1.CreateOptions) (result *v1.KubeVirt, err error) { + result = &v1.KubeVirt{} + err = c.client.Post(). + Namespace(c.ns). + Resource("kubevirts"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(kubeVirt). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a kubeVirt and updates it. Returns the server's representation of the kubeVirt, and an error, if there is any. +func (c *kubeVirts) Update(ctx context.Context, kubeVirt *v1.KubeVirt, opts metav1.UpdateOptions) (result *v1.KubeVirt, err error) { + result = &v1.KubeVirt{} + err = c.client.Put(). + Namespace(c.ns). + Resource("kubevirts"). + Name(kubeVirt.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(kubeVirt). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *kubeVirts) UpdateStatus(ctx context.Context, kubeVirt *v1.KubeVirt, opts metav1.UpdateOptions) (result *v1.KubeVirt, err error) { + result = &v1.KubeVirt{} + err = c.client.Put(). + Namespace(c.ns). + Resource("kubevirts"). + Name(kubeVirt.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(kubeVirt). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the kubeVirt and deletes it. Returns an error if one occurs. +func (c *kubeVirts) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("kubevirts"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *kubeVirts) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("kubevirts"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched kubeVirt. +func (c *kubeVirts) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.KubeVirt, err error) { + result = &v1.KubeVirt{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("kubevirts"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/virtualmachine.go b/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/virtualmachine.go new file mode 100644 index 00000000..b6dd7d53 --- /dev/null +++ b/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/virtualmachine.go @@ -0,0 +1,193 @@ +/* +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + scheme "github.com/cloud-bulldozer/k8s-netperf/pkg/kubevirt/client-go/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" + v1 "kubevirt.io/api/core/v1" +) + +// VirtualMachinesGetter has a method to return a VirtualMachineInterface. +// A group's client should implement this interface. +type VirtualMachinesGetter interface { + VirtualMachines(namespace string) VirtualMachineInterface +} + +// VirtualMachineInterface has methods to work with VirtualMachine resources. +type VirtualMachineInterface interface { + Create(ctx context.Context, virtualMachine *v1.VirtualMachine, opts metav1.CreateOptions) (*v1.VirtualMachine, error) + Update(ctx context.Context, virtualMachine *v1.VirtualMachine, opts metav1.UpdateOptions) (*v1.VirtualMachine, error) + UpdateStatus(ctx context.Context, virtualMachine *v1.VirtualMachine, opts metav1.UpdateOptions) (*v1.VirtualMachine, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.VirtualMachine, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.VirtualMachineList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.VirtualMachine, err error) + VirtualMachineExpansion +} + +// virtualMachines implements VirtualMachineInterface +type virtualMachines struct { + client rest.Interface + ns string +} + +// newVirtualMachines returns a VirtualMachines +func newVirtualMachines(c *KubevirtV1Client, namespace string) *virtualMachines { + return &virtualMachines{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the virtualMachine, and returns the corresponding virtualMachine object, and an error if there is any. +func (c *virtualMachines) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.VirtualMachine, err error) { + result = &v1.VirtualMachine{} + err = c.client.Get(). + Namespace(c.ns). + Resource("virtualmachines"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of VirtualMachines that match those selectors. +func (c *virtualMachines) List(ctx context.Context, opts metav1.ListOptions) (result *v1.VirtualMachineList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.VirtualMachineList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("virtualmachines"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested virtualMachines. +func (c *virtualMachines) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("virtualmachines"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a virtualMachine and creates it. Returns the server's representation of the virtualMachine, and an error, if there is any. +func (c *virtualMachines) Create(ctx context.Context, virtualMachine *v1.VirtualMachine, opts metav1.CreateOptions) (result *v1.VirtualMachine, err error) { + result = &v1.VirtualMachine{} + err = c.client.Post(). + Namespace(c.ns). + Resource("virtualmachines"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(virtualMachine). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a virtualMachine and updates it. Returns the server's representation of the virtualMachine, and an error, if there is any. +func (c *virtualMachines) Update(ctx context.Context, virtualMachine *v1.VirtualMachine, opts metav1.UpdateOptions) (result *v1.VirtualMachine, err error) { + result = &v1.VirtualMachine{} + err = c.client.Put(). + Namespace(c.ns). + Resource("virtualmachines"). + Name(virtualMachine.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(virtualMachine). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *virtualMachines) UpdateStatus(ctx context.Context, virtualMachine *v1.VirtualMachine, opts metav1.UpdateOptions) (result *v1.VirtualMachine, err error) { + result = &v1.VirtualMachine{} + err = c.client.Put(). + Namespace(c.ns). + Resource("virtualmachines"). + Name(virtualMachine.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(virtualMachine). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the virtualMachine and deletes it. Returns an error if one occurs. +func (c *virtualMachines) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("virtualmachines"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *virtualMachines) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("virtualmachines"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched virtualMachine. +func (c *virtualMachines) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.VirtualMachine, err error) { + result = &v1.VirtualMachine{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("virtualmachines"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/virtualmachineinstance.go b/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/virtualmachineinstance.go new file mode 100644 index 00000000..5766a757 --- /dev/null +++ b/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/virtualmachineinstance.go @@ -0,0 +1,193 @@ +/* +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + scheme "github.com/cloud-bulldozer/k8s-netperf/pkg/kubevirt/client-go/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" + v1 "kubevirt.io/api/core/v1" +) + +// VirtualMachineInstancesGetter has a method to return a VirtualMachineInstanceInterface. +// A group's client should implement this interface. +type VirtualMachineInstancesGetter interface { + VirtualMachineInstances(namespace string) VirtualMachineInstanceInterface +} + +// VirtualMachineInstanceInterface has methods to work with VirtualMachineInstance resources. +type VirtualMachineInstanceInterface interface { + Create(ctx context.Context, virtualMachineInstance *v1.VirtualMachineInstance, opts metav1.CreateOptions) (*v1.VirtualMachineInstance, error) + Update(ctx context.Context, virtualMachineInstance *v1.VirtualMachineInstance, opts metav1.UpdateOptions) (*v1.VirtualMachineInstance, error) + UpdateStatus(ctx context.Context, virtualMachineInstance *v1.VirtualMachineInstance, opts metav1.UpdateOptions) (*v1.VirtualMachineInstance, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.VirtualMachineInstance, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.VirtualMachineInstanceList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.VirtualMachineInstance, err error) + VirtualMachineInstanceExpansion +} + +// virtualMachineInstances implements VirtualMachineInstanceInterface +type virtualMachineInstances struct { + client rest.Interface + ns string +} + +// newVirtualMachineInstances returns a VirtualMachineInstances +func newVirtualMachineInstances(c *KubevirtV1Client, namespace string) *virtualMachineInstances { + return &virtualMachineInstances{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the virtualMachineInstance, and returns the corresponding virtualMachineInstance object, and an error if there is any. +func (c *virtualMachineInstances) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.VirtualMachineInstance, err error) { + result = &v1.VirtualMachineInstance{} + err = c.client.Get(). + Namespace(c.ns). + Resource("virtualmachineinstances"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of VirtualMachineInstances that match those selectors. +func (c *virtualMachineInstances) List(ctx context.Context, opts metav1.ListOptions) (result *v1.VirtualMachineInstanceList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.VirtualMachineInstanceList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("virtualmachineinstances"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested virtualMachineInstances. +func (c *virtualMachineInstances) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("virtualmachineinstances"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a virtualMachineInstance and creates it. Returns the server's representation of the virtualMachineInstance, and an error, if there is any. +func (c *virtualMachineInstances) Create(ctx context.Context, virtualMachineInstance *v1.VirtualMachineInstance, opts metav1.CreateOptions) (result *v1.VirtualMachineInstance, err error) { + result = &v1.VirtualMachineInstance{} + err = c.client.Post(). + Namespace(c.ns). + Resource("virtualmachineinstances"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(virtualMachineInstance). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a virtualMachineInstance and updates it. Returns the server's representation of the virtualMachineInstance, and an error, if there is any. +func (c *virtualMachineInstances) Update(ctx context.Context, virtualMachineInstance *v1.VirtualMachineInstance, opts metav1.UpdateOptions) (result *v1.VirtualMachineInstance, err error) { + result = &v1.VirtualMachineInstance{} + err = c.client.Put(). + Namespace(c.ns). + Resource("virtualmachineinstances"). + Name(virtualMachineInstance.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(virtualMachineInstance). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *virtualMachineInstances) UpdateStatus(ctx context.Context, virtualMachineInstance *v1.VirtualMachineInstance, opts metav1.UpdateOptions) (result *v1.VirtualMachineInstance, err error) { + result = &v1.VirtualMachineInstance{} + err = c.client.Put(). + Namespace(c.ns). + Resource("virtualmachineinstances"). + Name(virtualMachineInstance.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(virtualMachineInstance). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the virtualMachineInstance and deletes it. Returns an error if one occurs. +func (c *virtualMachineInstances) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("virtualmachineinstances"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *virtualMachineInstances) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("virtualmachineinstances"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched virtualMachineInstance. +func (c *virtualMachineInstances) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.VirtualMachineInstance, err error) { + result = &v1.VirtualMachineInstance{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("virtualmachineinstances"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/virtualmachineinstancemigration.go b/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/virtualmachineinstancemigration.go new file mode 100644 index 00000000..154564bd --- /dev/null +++ b/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/virtualmachineinstancemigration.go @@ -0,0 +1,193 @@ +/* +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + scheme "github.com/cloud-bulldozer/k8s-netperf/pkg/kubevirt/client-go/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" + v1 "kubevirt.io/api/core/v1" +) + +// VirtualMachineInstanceMigrationsGetter has a method to return a VirtualMachineInstanceMigrationInterface. +// A group's client should implement this interface. +type VirtualMachineInstanceMigrationsGetter interface { + VirtualMachineInstanceMigrations(namespace string) VirtualMachineInstanceMigrationInterface +} + +// VirtualMachineInstanceMigrationInterface has methods to work with VirtualMachineInstanceMigration resources. +type VirtualMachineInstanceMigrationInterface interface { + Create(ctx context.Context, virtualMachineInstanceMigration *v1.VirtualMachineInstanceMigration, opts metav1.CreateOptions) (*v1.VirtualMachineInstanceMigration, error) + Update(ctx context.Context, virtualMachineInstanceMigration *v1.VirtualMachineInstanceMigration, opts metav1.UpdateOptions) (*v1.VirtualMachineInstanceMigration, error) + UpdateStatus(ctx context.Context, virtualMachineInstanceMigration *v1.VirtualMachineInstanceMigration, opts metav1.UpdateOptions) (*v1.VirtualMachineInstanceMigration, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.VirtualMachineInstanceMigration, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.VirtualMachineInstanceMigrationList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.VirtualMachineInstanceMigration, err error) + VirtualMachineInstanceMigrationExpansion +} + +// virtualMachineInstanceMigrations implements VirtualMachineInstanceMigrationInterface +type virtualMachineInstanceMigrations struct { + client rest.Interface + ns string +} + +// newVirtualMachineInstanceMigrations returns a VirtualMachineInstanceMigrations +func newVirtualMachineInstanceMigrations(c *KubevirtV1Client, namespace string) *virtualMachineInstanceMigrations { + return &virtualMachineInstanceMigrations{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the virtualMachineInstanceMigration, and returns the corresponding virtualMachineInstanceMigration object, and an error if there is any. +func (c *virtualMachineInstanceMigrations) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.VirtualMachineInstanceMigration, err error) { + result = &v1.VirtualMachineInstanceMigration{} + err = c.client.Get(). + Namespace(c.ns). + Resource("virtualmachineinstancemigrations"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of VirtualMachineInstanceMigrations that match those selectors. +func (c *virtualMachineInstanceMigrations) List(ctx context.Context, opts metav1.ListOptions) (result *v1.VirtualMachineInstanceMigrationList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.VirtualMachineInstanceMigrationList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("virtualmachineinstancemigrations"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested virtualMachineInstanceMigrations. +func (c *virtualMachineInstanceMigrations) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("virtualmachineinstancemigrations"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a virtualMachineInstanceMigration and creates it. Returns the server's representation of the virtualMachineInstanceMigration, and an error, if there is any. +func (c *virtualMachineInstanceMigrations) Create(ctx context.Context, virtualMachineInstanceMigration *v1.VirtualMachineInstanceMigration, opts metav1.CreateOptions) (result *v1.VirtualMachineInstanceMigration, err error) { + result = &v1.VirtualMachineInstanceMigration{} + err = c.client.Post(). + Namespace(c.ns). + Resource("virtualmachineinstancemigrations"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(virtualMachineInstanceMigration). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a virtualMachineInstanceMigration and updates it. Returns the server's representation of the virtualMachineInstanceMigration, and an error, if there is any. +func (c *virtualMachineInstanceMigrations) Update(ctx context.Context, virtualMachineInstanceMigration *v1.VirtualMachineInstanceMigration, opts metav1.UpdateOptions) (result *v1.VirtualMachineInstanceMigration, err error) { + result = &v1.VirtualMachineInstanceMigration{} + err = c.client.Put(). + Namespace(c.ns). + Resource("virtualmachineinstancemigrations"). + Name(virtualMachineInstanceMigration.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(virtualMachineInstanceMigration). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *virtualMachineInstanceMigrations) UpdateStatus(ctx context.Context, virtualMachineInstanceMigration *v1.VirtualMachineInstanceMigration, opts metav1.UpdateOptions) (result *v1.VirtualMachineInstanceMigration, err error) { + result = &v1.VirtualMachineInstanceMigration{} + err = c.client.Put(). + Namespace(c.ns). + Resource("virtualmachineinstancemigrations"). + Name(virtualMachineInstanceMigration.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(virtualMachineInstanceMigration). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the virtualMachineInstanceMigration and deletes it. Returns an error if one occurs. +func (c *virtualMachineInstanceMigrations) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("virtualmachineinstancemigrations"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *virtualMachineInstanceMigrations) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("virtualmachineinstancemigrations"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched virtualMachineInstanceMigration. +func (c *virtualMachineInstanceMigrations) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.VirtualMachineInstanceMigration, err error) { + result = &v1.VirtualMachineInstanceMigration{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("virtualmachineinstancemigrations"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/virtualmachineinstancepreset.go b/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/virtualmachineinstancepreset.go new file mode 100644 index 00000000..cf1aa18b --- /dev/null +++ b/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/virtualmachineinstancepreset.go @@ -0,0 +1,176 @@ +/* +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + scheme "github.com/cloud-bulldozer/k8s-netperf/pkg/kubevirt/client-go/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" + v1 "kubevirt.io/api/core/v1" +) + +// VirtualMachineInstancePresetsGetter has a method to return a VirtualMachineInstancePresetInterface. +// A group's client should implement this interface. +type VirtualMachineInstancePresetsGetter interface { + VirtualMachineInstancePresets(namespace string) VirtualMachineInstancePresetInterface +} + +// VirtualMachineInstancePresetInterface has methods to work with VirtualMachineInstancePreset resources. +type VirtualMachineInstancePresetInterface interface { + Create(ctx context.Context, virtualMachineInstancePreset *v1.VirtualMachineInstancePreset, opts metav1.CreateOptions) (*v1.VirtualMachineInstancePreset, error) + Update(ctx context.Context, virtualMachineInstancePreset *v1.VirtualMachineInstancePreset, opts metav1.UpdateOptions) (*v1.VirtualMachineInstancePreset, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.VirtualMachineInstancePreset, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.VirtualMachineInstancePresetList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.VirtualMachineInstancePreset, err error) + VirtualMachineInstancePresetExpansion +} + +// virtualMachineInstancePresets implements VirtualMachineInstancePresetInterface +type virtualMachineInstancePresets struct { + client rest.Interface + ns string +} + +// newVirtualMachineInstancePresets returns a VirtualMachineInstancePresets +func newVirtualMachineInstancePresets(c *KubevirtV1Client, namespace string) *virtualMachineInstancePresets { + return &virtualMachineInstancePresets{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the virtualMachineInstancePreset, and returns the corresponding virtualMachineInstancePreset object, and an error if there is any. +func (c *virtualMachineInstancePresets) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.VirtualMachineInstancePreset, err error) { + result = &v1.VirtualMachineInstancePreset{} + err = c.client.Get(). + Namespace(c.ns). + Resource("virtualmachineinstancepresets"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of VirtualMachineInstancePresets that match those selectors. +func (c *virtualMachineInstancePresets) List(ctx context.Context, opts metav1.ListOptions) (result *v1.VirtualMachineInstancePresetList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.VirtualMachineInstancePresetList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("virtualmachineinstancepresets"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested virtualMachineInstancePresets. +func (c *virtualMachineInstancePresets) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("virtualmachineinstancepresets"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a virtualMachineInstancePreset and creates it. Returns the server's representation of the virtualMachineInstancePreset, and an error, if there is any. +func (c *virtualMachineInstancePresets) Create(ctx context.Context, virtualMachineInstancePreset *v1.VirtualMachineInstancePreset, opts metav1.CreateOptions) (result *v1.VirtualMachineInstancePreset, err error) { + result = &v1.VirtualMachineInstancePreset{} + err = c.client.Post(). + Namespace(c.ns). + Resource("virtualmachineinstancepresets"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(virtualMachineInstancePreset). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a virtualMachineInstancePreset and updates it. Returns the server's representation of the virtualMachineInstancePreset, and an error, if there is any. +func (c *virtualMachineInstancePresets) Update(ctx context.Context, virtualMachineInstancePreset *v1.VirtualMachineInstancePreset, opts metav1.UpdateOptions) (result *v1.VirtualMachineInstancePreset, err error) { + result = &v1.VirtualMachineInstancePreset{} + err = c.client.Put(). + Namespace(c.ns). + Resource("virtualmachineinstancepresets"). + Name(virtualMachineInstancePreset.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(virtualMachineInstancePreset). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the virtualMachineInstancePreset and deletes it. Returns an error if one occurs. +func (c *virtualMachineInstancePresets) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("virtualmachineinstancepresets"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *virtualMachineInstancePresets) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("virtualmachineinstancepresets"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched virtualMachineInstancePreset. +func (c *virtualMachineInstancePresets) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.VirtualMachineInstancePreset, err error) { + result = &v1.VirtualMachineInstancePreset{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("virtualmachineinstancepresets"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/virtualmachineinstancereplicaset.go b/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/virtualmachineinstancereplicaset.go new file mode 100644 index 00000000..47e22a4f --- /dev/null +++ b/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1/virtualmachineinstancereplicaset.go @@ -0,0 +1,193 @@ +/* +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + scheme "github.com/cloud-bulldozer/k8s-netperf/pkg/kubevirt/client-go/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" + v1 "kubevirt.io/api/core/v1" +) + +// VirtualMachineInstanceReplicaSetsGetter has a method to return a VirtualMachineInstanceReplicaSetInterface. +// A group's client should implement this interface. +type VirtualMachineInstanceReplicaSetsGetter interface { + VirtualMachineInstanceReplicaSets(namespace string) VirtualMachineInstanceReplicaSetInterface +} + +// VirtualMachineInstanceReplicaSetInterface has methods to work with VirtualMachineInstanceReplicaSet resources. +type VirtualMachineInstanceReplicaSetInterface interface { + Create(ctx context.Context, virtualMachineInstanceReplicaSet *v1.VirtualMachineInstanceReplicaSet, opts metav1.CreateOptions) (*v1.VirtualMachineInstanceReplicaSet, error) + Update(ctx context.Context, virtualMachineInstanceReplicaSet *v1.VirtualMachineInstanceReplicaSet, opts metav1.UpdateOptions) (*v1.VirtualMachineInstanceReplicaSet, error) + UpdateStatus(ctx context.Context, virtualMachineInstanceReplicaSet *v1.VirtualMachineInstanceReplicaSet, opts metav1.UpdateOptions) (*v1.VirtualMachineInstanceReplicaSet, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.VirtualMachineInstanceReplicaSet, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.VirtualMachineInstanceReplicaSetList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.VirtualMachineInstanceReplicaSet, err error) + VirtualMachineInstanceReplicaSetExpansion +} + +// virtualMachineInstanceReplicaSets implements VirtualMachineInstanceReplicaSetInterface +type virtualMachineInstanceReplicaSets struct { + client rest.Interface + ns string +} + +// newVirtualMachineInstanceReplicaSets returns a VirtualMachineInstanceReplicaSets +func newVirtualMachineInstanceReplicaSets(c *KubevirtV1Client, namespace string) *virtualMachineInstanceReplicaSets { + return &virtualMachineInstanceReplicaSets{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the virtualMachineInstanceReplicaSet, and returns the corresponding virtualMachineInstanceReplicaSet object, and an error if there is any. +func (c *virtualMachineInstanceReplicaSets) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.VirtualMachineInstanceReplicaSet, err error) { + result = &v1.VirtualMachineInstanceReplicaSet{} + err = c.client.Get(). + Namespace(c.ns). + Resource("virtualmachineinstancereplicasets"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of VirtualMachineInstanceReplicaSets that match those selectors. +func (c *virtualMachineInstanceReplicaSets) List(ctx context.Context, opts metav1.ListOptions) (result *v1.VirtualMachineInstanceReplicaSetList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.VirtualMachineInstanceReplicaSetList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("virtualmachineinstancereplicasets"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested virtualMachineInstanceReplicaSets. +func (c *virtualMachineInstanceReplicaSets) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("virtualmachineinstancereplicasets"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a virtualMachineInstanceReplicaSet and creates it. Returns the server's representation of the virtualMachineInstanceReplicaSet, and an error, if there is any. +func (c *virtualMachineInstanceReplicaSets) Create(ctx context.Context, virtualMachineInstanceReplicaSet *v1.VirtualMachineInstanceReplicaSet, opts metav1.CreateOptions) (result *v1.VirtualMachineInstanceReplicaSet, err error) { + result = &v1.VirtualMachineInstanceReplicaSet{} + err = c.client.Post(). + Namespace(c.ns). + Resource("virtualmachineinstancereplicasets"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(virtualMachineInstanceReplicaSet). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a virtualMachineInstanceReplicaSet and updates it. Returns the server's representation of the virtualMachineInstanceReplicaSet, and an error, if there is any. +func (c *virtualMachineInstanceReplicaSets) Update(ctx context.Context, virtualMachineInstanceReplicaSet *v1.VirtualMachineInstanceReplicaSet, opts metav1.UpdateOptions) (result *v1.VirtualMachineInstanceReplicaSet, err error) { + result = &v1.VirtualMachineInstanceReplicaSet{} + err = c.client.Put(). + Namespace(c.ns). + Resource("virtualmachineinstancereplicasets"). + Name(virtualMachineInstanceReplicaSet.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(virtualMachineInstanceReplicaSet). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *virtualMachineInstanceReplicaSets) UpdateStatus(ctx context.Context, virtualMachineInstanceReplicaSet *v1.VirtualMachineInstanceReplicaSet, opts metav1.UpdateOptions) (result *v1.VirtualMachineInstanceReplicaSet, err error) { + result = &v1.VirtualMachineInstanceReplicaSet{} + err = c.client.Put(). + Namespace(c.ns). + Resource("virtualmachineinstancereplicasets"). + Name(virtualMachineInstanceReplicaSet.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(virtualMachineInstanceReplicaSet). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the virtualMachineInstanceReplicaSet and deletes it. Returns an error if one occurs. +func (c *virtualMachineInstanceReplicaSets) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("virtualmachineinstancereplicasets"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *virtualMachineInstanceReplicaSets) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("virtualmachineinstancereplicasets"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched virtualMachineInstanceReplicaSet. +func (c *virtualMachineInstanceReplicaSets) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.VirtualMachineInstanceReplicaSet, err error) { + result = &v1.VirtualMachineInstanceReplicaSet{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("virtualmachineinstancereplicasets"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} From 137d5e08e14c3b66c812820c87f46a443d65cb96 Mon Sep 17 00:00:00 2001 From: Joe Talerico aka rook Date: Wed, 28 Aug 2024 13:42:36 -0400 Subject: [PATCH 03/19] Cleaning up. Creating kubevirt.go under k8s Creating function and testing the ssh mechanism Signed-off-by: Joe Talerico aka rook --- cmd/k8s-netperf/k8s-netperf.go | 52 ++------------- pkg/k8s/kubevirt.go | 118 +++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+), 47 deletions(-) create mode 100644 pkg/k8s/kubevirt.go diff --git a/cmd/k8s-netperf/k8s-netperf.go b/cmd/k8s-netperf/k8s-netperf.go index 16def9e6..b2663eef 100644 --- a/cmd/k8s-netperf/k8s-netperf.go +++ b/cmd/k8s-netperf/k8s-netperf.go @@ -26,7 +26,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" - v1 "kubevirt.io/api/core/v1" ) const index = "k8s-netperf" @@ -155,52 +154,11 @@ var rootCmd = &cobra.Command{ if err != nil { log.Error(err) } - kclient.VirtualMachineInstances("netperf").Create(context.TODO(), &v1.VirtualMachineInstance{ - Spec: v1.VirtualMachineInstanceSpec{ - Domain: v1.DomainSpec{ - CPU: &v1.CPU{ - Sockets: 2, - Cores: 2, - Threads: 1, - }, - Devices: v1.Devices{ - Disks: []v1.Disk{ - v1.Disk{ - Name: "disk0", - DiskDevice: v1.DiskDevice{ - Disk: &v1.DiskTarget{ - Bus: "virtio", - }, - }, - }, - }, - }, - }, - Volumes: []v1.Volume{ - v1.Volume{ - Name: "disk0", - VolumeSource: v1.VolumeSource{ - ContainerDisk: &v1.ContainerDiskSource{ - Image: "kubevirt/fedora-cloud-container-disk-demo:latest", - }, - }, - }, - v1.Volume{ - Name: "cloudinit", - VolumeSource: v1.VolumeSource{ - CloudInitNoCloud: &v1.CloudInitNoCloudSource{ - UserData: `#cloud-config - password: fedora - chpasswd: { expire: False } - runcmd: - - dnf install -y uperf iperf3 git ethtool`, - }, - }, - }, - }, - }, - }, metav1.CreateOptions{}) - os.Exit(1) + _, err = k8s.CreateVMServer(kclient, "server") + if err != nil { + log.Error(err) + } + k8s.WaitForVMI(kclient, "server") } // Build the SUT (Deployments) diff --git a/pkg/k8s/kubevirt.go b/pkg/k8s/kubevirt.go new file mode 100644 index 00000000..cb796201 --- /dev/null +++ b/pkg/k8s/kubevirt.go @@ -0,0 +1,118 @@ +package k8s + +import ( + "context" + "fmt" + "os" + + b64 "encoding/base64" + + kubevirtv1 "github.com/cloud-bulldozer/k8s-netperf/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1" + k8sv1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "kubevirt.io/api/core/v1" +) + +func CreateVMServer(client *kubevirtv1.KubevirtV1Client, name string) (*v1.VirtualMachineInstance, error) { + dirname, err := os.UserHomeDir() + if err != nil { + return nil, err + } + ssh, err := os.ReadFile(fmt.Sprintf("%s/.ssh/id_rsa.pub", dirname)) + if err != nil { + return nil, err + } + data := fmt.Sprintf(`#cloud-config +runcmd: + - dnf install -y uperf iperf3 git ethtool +users: + - name: fedora + groups: sudo + shell: /bin/bash + ssh_authorized_keys: + - %s +ssh_deletekeys: false +password: fedora +chpasswd: { expire: False }`, string(ssh)) + return CreateVMI(client, name, b64.StdEncoding.EncodeToString([]byte(data))) + +} + +func CreateVMI(client *kubevirtv1.KubevirtV1Client, name string, b64data string) (*v1.VirtualMachineInstance, error) { + vmi, err := client.VirtualMachineInstances(namespace).Create(context.TODO(), &v1.VirtualMachineInstance{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Spec: v1.VirtualMachineInstanceSpec{ + Domain: v1.DomainSpec{ + Resources: v1.ResourceRequirements{ + Requests: k8sv1.ResourceList{ + k8sv1.ResourceMemory: resource.MustParse("4096Mi"), + k8sv1.ResourceCPU: resource.MustParse("500m"), + }, + }, + CPU: &v1.CPU{ + Sockets: 2, + Cores: 2, + Threads: 1, + }, + Devices: v1.Devices{ + Disks: []v1.Disk{ + v1.Disk{ + Name: "disk0", + DiskDevice: v1.DiskDevice{ + Disk: &v1.DiskTarget{ + Bus: "virtio", + }, + }, + }, + }, + }, + }, + Volumes: []v1.Volume{ + v1.Volume{ + Name: "disk0", + VolumeSource: v1.VolumeSource{ + ContainerDisk: &v1.ContainerDiskSource{ + Image: "kubevirt/fedora-cloud-container-disk-demo:latest", + }, + }, + }, + v1.Volume{ + Name: "cloudinit", + VolumeSource: v1.VolumeSource{ + CloudInitNoCloud: &v1.CloudInitNoCloudSource{ + UserDataBase64: b64data, + }, + }, + }, + }, + }, + }, metav1.CreateOptions{}) + if err != nil { + return vmi, err + } + return vmi, nil +} + +func WaitForVMI(client *kubevirtv1.KubevirtV1Client, name string) error { + vmw, err := client.VirtualMachineInstances(namespace).Watch(context.TODO(), metav1.ListOptions{}) + if err != nil { + return err + } + defer vmw.Stop() + for event := range vmw.ResultChan() { + d, ok := event.Object.(*v1.VirtualMachineInstance) + if !ok { + return fmt.Errorf("Unable to watch VMI %s", name) + } + if d.Name == name { + if d.Status.Phase == "Running" { + return nil + } + } + } + return nil +} From bb861ee63e3194c0fb4e2182fd307720e8105fb7 Mon Sep 17 00:00:00 2001 From: Joe Talerico aka rook Date: Thu, 29 Aug 2024 15:11:01 -0400 Subject: [PATCH 04/19] Attempting to setup routes to hit VMs with ssh Signed-off-by: Joe Talerico aka rook --- cmd/k8s-netperf/k8s-netperf.go | 20 +++++ pkg/config/config.go | 2 + pkg/k8s/kubevirt.go | 157 +++++++++++++++++++++++++++++++-- 3 files changed, 173 insertions(+), 6 deletions(-) diff --git a/cmd/k8s-netperf/k8s-netperf.go b/cmd/k8s-netperf/k8s-netperf.go index b2663eef..616eac4c 100644 --- a/cmd/k8s-netperf/k8s-netperf.go +++ b/cmd/k8s-netperf/k8s-netperf.go @@ -24,6 +24,7 @@ import ( "github.com/google/uuid" "github.com/spf13/cobra" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" ) @@ -150,6 +151,11 @@ var rootCmd = &cobra.Command{ } if vm { + // Create a dynamic client + dynClient, err := dynamic.NewForConfig(rconfig) + if err != nil { + log.Error(err) + } kclient, err := kubevirtv1.NewForConfig(rconfig) if err != nil { log.Error(err) @@ -159,6 +165,20 @@ var rootCmd = &cobra.Command{ log.Error(err) } k8s.WaitForVMI(kclient, "server") + host, err := k8s.CreateVMClient(kclient, client, dynClient, "client") + if err != nil { + log.Error(err) + } + update := k8s.UpdateConfig(&s.Configs, host) + for _, cfg := range update { + log.Info(cfg.Profile) + log.Info(cfg.VM) + log.Info(cfg.VMHost) + } + log.Info(host) + k8s.WaitForVMI(kclient, "client") + os.Exit(0) + } // Build the SUT (Deployments) diff --git a/pkg/config/config.go b/pkg/config/config.go index 8daeb3db..45c7bec4 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -22,6 +22,8 @@ type Config struct { Samples int `yaml:"samples,omitempty"` MessageSize int `yaml:"messagesize,omitempty"` Service bool `default:"false" yaml:"service,omitempty"` + VM bool + VMHost string Metric string AcrossAZ bool } diff --git a/pkg/k8s/kubevirt.go b/pkg/k8s/kubevirt.go index cb796201..d8c544e2 100644 --- a/pkg/k8s/kubevirt.go +++ b/pkg/k8s/kubevirt.go @@ -7,14 +7,148 @@ import ( b64 "encoding/base64" + "github.com/cloud-bulldozer/k8s-netperf/pkg/config" kubevirtv1 "github.com/cloud-bulldozer/k8s-netperf/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1" + log "github.com/cloud-bulldozer/k8s-netperf/pkg/logging" + corev1 "k8s.io/api/core/v1" k8sv1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/intstr" + "k8s.io/client-go/dynamic" + "k8s.io/client-go/kubernetes" v1 "kubevirt.io/api/core/v1" ) +func UpdateConfig(nc *[]config.Config, host string) []config.Config { + update := make([]config.Config, len(*nc)) + for _, cfg := range *nc { + cfg.VM = true + cfg.VMHost = host + update = append(update, cfg) + } + return update +} + +func createCommService(client *kubernetes.Clientset, label map[string]string, name string) error { + log.Infof("🚀 Creating service for %s in namespace %s", name, namespace) + sc := client.CoreV1().Services(namespace) + service := &corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Spec: corev1.ServiceSpec{ + Ports: []corev1.ServicePort{ + { + Name: fmt.Sprintf("%s", name), + Protocol: corev1.ProtocolTCP, + NodePort: 32022, + TargetPort: intstr.Parse(fmt.Sprintf("%d", 22)), + Port: 22, + }, + }, + Type: corev1.ServiceType("NodePort"), + Selector: label, + }, + } + _, err := sc.Create(context.TODO(), service, metav1.CreateOptions{}) + return err +} + +func exposeService(client *kubernetes.Clientset, dynamicClient *dynamic.DynamicClient, svcName string) (string, error) { + gvr := schema.GroupVersionResource{ + Group: "route.openshift.io", + Version: "v1", + Resource: "routes", + } + + route := &unstructured.Unstructured{ + Object: map[string]interface{}{ + "apiVersion": "route.openshift.io/v1", + "kind": "Route", + "metadata": map[string]interface{}{ + "name": fmt.Sprintf("svc-%s-route", svcName), + "namespace": namespace, + }, + "spec": map[string]interface{}{ + "port": map[string]interface{}{ + "targetPort": 22, + }, + "to": map[string]interface{}{ + "kind": "Service", + "name": svcName, + "weight": 100, + }, + "wildcardPolicy": "None", + }, + }, + } + route, err := dynamicClient.Resource(gvr).Namespace(namespace).Create(context.TODO(), route, metav1.CreateOptions{}) + if err != nil { + return "", fmt.Errorf("failed to create route: %v", err) + } + retrievedRoute, err := dynamicClient.Resource(gvr).Namespace(namespace).Get(context.TODO(), route.GetName(), metav1.GetOptions{}) + if err != nil { + log.Fatalf("error retrieving route: %v", err) + } + spec, ok := retrievedRoute.Object["spec"].(map[string]interface{}) + if !ok { + return "", fmt.Errorf("error extracting spec from route") + } + host, ok := spec["host"].(string) + if !ok { + return "", fmt.Errorf("host not found in route spec") + } + return host, nil +} + +func CreateVMClient(kclient *kubevirtv1.KubevirtV1Client, client *kubernetes.Clientset, dyn *dynamic.DynamicClient, name string) (string, error) { + label := map[string]string{ + "app": fmt.Sprintf("%s", name), + } + dirname, err := os.UserHomeDir() + if err != nil { + return "", err + } + ssh, err := os.ReadFile(fmt.Sprintf("%s/.ssh/id_rsa.pub", dirname)) + if err != nil { + return "", err + } + data := fmt.Sprintf(`#cloud-config +users: + - name: fedora + groups: sudo + shell: /bin/bash + ssh_authorized_keys: + - %s +ssh_deletekeys: false +password: fedora +chpasswd: { expire: False } +runcmd: + - dnf install -y uperf iperf3 git ethtool +`, string(ssh)) + _, err = CreateVMI(kclient, name, label, b64.StdEncoding.EncodeToString([]byte(data))) + if err != nil { + return "", err + } + err = createCommService(client, label, fmt.Sprintf("%s-svc", name)) + if err != nil { + return "", err + } + host, err := exposeService(client, dyn, fmt.Sprintf("%s-svc", name)) + if err != nil { + return "", err + } + return host, nil +} + func CreateVMServer(client *kubevirtv1.KubevirtV1Client, name string) (*v1.VirtualMachineInstance, error) { + label := map[string]string{ + "app": fmt.Sprintf("%s", name), + } dirname, err := os.UserHomeDir() if err != nil { return nil, err @@ -24,8 +158,6 @@ func CreateVMServer(client *kubevirtv1.KubevirtV1Client, name string) (*v1.Virtu return nil, err } data := fmt.Sprintf(`#cloud-config -runcmd: - - dnf install -y uperf iperf3 git ethtool users: - name: fedora groups: sudo @@ -34,18 +166,30 @@ users: - %s ssh_deletekeys: false password: fedora -chpasswd: { expire: False }`, string(ssh)) - return CreateVMI(client, name, b64.StdEncoding.EncodeToString([]byte(data))) - +chpasswd: { expire: False } +runcmd: + - dnf install -y uperf iperf3 git ethtool + - uperf -s -v & + - iperf3 -s & +`, string(ssh)) + return CreateVMI(client, name, label, b64.StdEncoding.EncodeToString([]byte(data))) } -func CreateVMI(client *kubevirtv1.KubevirtV1Client, name string, b64data string) (*v1.VirtualMachineInstance, error) { +func CreateVMI(client *kubevirtv1.KubevirtV1Client, name string, label map[string]string, b64data string) (*v1.VirtualMachineInstance, error) { + delSeconds := int64(0) + mutliQ := true vmi, err := client.VirtualMachineInstances(namespace).Create(context.TODO(), &v1.VirtualMachineInstance{ + TypeMeta: metav1.TypeMeta{ + APIVersion: v1.GroupVersion.String(), + Kind: "VirtualMachineInstance", + }, ObjectMeta: metav1.ObjectMeta{ Name: name, Namespace: namespace, + Labels: label, }, Spec: v1.VirtualMachineInstanceSpec{ + TerminationGracePeriodSeconds: &delSeconds, Domain: v1.DomainSpec{ Resources: v1.ResourceRequirements{ Requests: k8sv1.ResourceList{ @@ -59,6 +203,7 @@ func CreateVMI(client *kubevirtv1.KubevirtV1Client, name string, b64data string) Threads: 1, }, Devices: v1.Devices{ + NetworkInterfaceMultiQueue: &mutliQ, Disks: []v1.Disk{ v1.Disk{ Name: "disk0", From faf37b8a3e86fb70295b9063b8f3f69de58c591a Mon Sep 17 00:00:00 2001 From: Joe Talerico aka rook Date: Fri, 30 Aug 2024 13:29:33 -0400 Subject: [PATCH 05/19] Affinity Seeing about building the infra and reuing Affinity logic Signed-off-by: Joe Talerico aka rook --- cmd/k8s-netperf/k8s-netperf.go | 59 +++++-------- pkg/config/config.go | 8 +- pkg/k8s/kubernetes.go | 153 +++++++++++---------------------- pkg/k8s/kubevirt.go | 38 ++++---- 4 files changed, 101 insertions(+), 157 deletions(-) diff --git a/cmd/k8s-netperf/k8s-netperf.go b/cmd/k8s-netperf/k8s-netperf.go index 616eac4c..97013900 100644 --- a/cmd/k8s-netperf/k8s-netperf.go +++ b/cmd/k8s-netperf/k8s-netperf.go @@ -151,6 +151,7 @@ var rootCmd = &cobra.Command{ } if vm { + s.VM = true // Create a dynamic client dynClient, err := dynamic.NewForConfig(rconfig) if err != nil { @@ -160,25 +161,8 @@ var rootCmd = &cobra.Command{ if err != nil { log.Error(err) } - _, err = k8s.CreateVMServer(kclient, "server") - if err != nil { - log.Error(err) - } - k8s.WaitForVMI(kclient, "server") - host, err := k8s.CreateVMClient(kclient, client, dynClient, "client") - if err != nil { - log.Error(err) - } - update := k8s.UpdateConfig(&s.Configs, host) - for _, cfg := range update { - log.Info(cfg.Profile) - log.Info(cfg.VM) - log.Info(cfg.VMHost) - } - log.Info(host) - k8s.WaitForVMI(kclient, "client") - os.Exit(0) - + s.KClient = kclient + s.DClient = dynClient } // Build the SUT (Deployments) @@ -208,28 +192,31 @@ var rootCmd = &cobra.Command{ if iperf3 { requestedDrivers = append(requestedDrivers, "iperf3") } + // Run through each test - for _, nc := range s.Configs { - // Determine the metric for the test - metric := string("OP/s") - if strings.Contains(nc.Profile, "STREAM") { - metric = "Mb/s" - } - nc.Metric = metric - nc.AcrossAZ = acrossAZ - // No need to run hostNetwork through Service. - var pr result.Data - for _, driver := range requestedDrivers { - if s.HostNetwork && !nc.Service { - pr = executeWorkload(nc, s, true, driver) + if !s.VM { + for _, nc := range s.Configs { + // Determine the metric for the test + metric := string("OP/s") + if strings.Contains(nc.Profile, "STREAM") { + metric = "Mb/s" + } + nc.Metric = metric + nc.AcrossAZ = acrossAZ + // No need to run hostNetwork through Service. + var pr result.Data + for _, driver := range requestedDrivers { + if s.HostNetwork && !nc.Service { + pr = executeWorkload(nc, s, true, driver) + if len(pr.Profile) > 1 { + sr.Results = append(sr.Results, pr) + } + } + pr = executeWorkload(nc, s, false, driver) if len(pr.Profile) > 1 { sr.Results = append(sr.Results, pr) } } - pr = executeWorkload(nc, s, false, driver) - if len(pr.Profile) > 1 { - sr.Results = append(sr.Results, pr) - } } } diff --git a/pkg/config/config.go b/pkg/config/config.go index 45c7bec4..d4382b56 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -5,11 +5,13 @@ import ( "os" "regexp" + kubevirtv1 "github.com/cloud-bulldozer/k8s-netperf/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1" apiv1 "k8s.io/api/core/v1" log "github.com/cloud-bulldozer/k8s-netperf/pkg/logging" "github.com/cloud-bulldozer/k8s-netperf/pkg/metrics" "gopkg.in/yaml.v3" + "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" ) @@ -22,8 +24,6 @@ type Config struct { Samples int `yaml:"samples,omitempty"` MessageSize int `yaml:"messagesize,omitempty"` Service bool `default:"false" yaml:"service,omitempty"` - VM bool - VMHost string Metric string AcrossAZ bool } @@ -34,6 +34,8 @@ type PerfScenarios struct { AcrossAZ bool HostNetwork bool Configs []Config + VM bool + VMHost string ServerNodeInfo metrics.NodeInfo ClientNodeInfo metrics.NodeInfo Client apiv1.PodList @@ -46,6 +48,8 @@ type PerfScenarios struct { UperfService *apiv1.Service RestConfig rest.Config ClientSet *kubernetes.Clientset + KClient *kubevirtv1.KubevirtV1Client + DClient *dynamic.DynamicClient } // Tests we will support in k8s-netperf diff --git a/pkg/k8s/kubernetes.go b/pkg/k8s/kubernetes.go index 622d7281..5db9a0ff 100644 --- a/pkg/k8s/kubernetes.go +++ b/pkg/k8s/kubernetes.go @@ -11,11 +11,8 @@ import ( corev1 "k8s.io/api/core/v1" v1 "k8s.io/api/rbac/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/watch" - "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes" "k8s.io/utils/pointer" ) @@ -213,7 +210,9 @@ func BuildSUT(client *kubernetes.Clientset, s *config.PerfScenarios) error { cdp.NodeAffinity = corev1.NodeAffinity{ RequiredDuringSchedulingIgnoredDuringExecution: workerNodeSelectorExpression, } - s.Client, err = deployDeployment(client, cdp) + if !s.VM { + s.Client, err = deployDeployment(client, cdp) + } if err != nil { return err } @@ -306,15 +305,30 @@ func BuildSUT(client *kubernetes.Clientset, s *config.PerfScenarios) error { cdpHostAcross.PodAntiAffinity = corev1.PodAntiAffinity{ RequiredDuringSchedulingIgnoredDuringExecution: clientRoleAffinity, } - s.ClientHost, err = deployDeployment(client, cdpHostAcross) - } - if err != nil { - return err + if !s.VM { + s.ClientHost, err = deployDeployment(client, cdpHostAcross) + if err != nil { + return err + } + } else { + _, err := CreateVMClient(s.KClient, client, s.DClient, clientAcrossRole, clientAcrossRole, &cdpHostAcross.PodAntiAffinity, &cdpHostAcross.NodeAffinity) + if err != nil { + return err + } + } } - s.ClientAcross, err = deployDeployment(client, cdpAcross) - if err != nil { - return err + if !s.VM { + s.ClientAcross, err = deployDeployment(client, cdpAcross) + if err != nil { + return err + } + } else { + _, err := CreateVMClient(s.KClient, client, s.DClient, clientAcrossRole, clientAcrossRole, &cdpAcross.PodAntiAffinity, &cdpHostAcross.NodeAffinity) + if err != nil { + return err + } } + } // Use separate containers for servers @@ -397,101 +411,38 @@ func BuildSUT(client *kubernetes.Clientset, s *config.PerfScenarios) error { if ncount > 1 { if s.HostNetwork { - s.ServerHost, err = deployDeployment(client, sdpHost) - if err != nil { - return err + if !s.VM { + s.ServerHost, err = deployDeployment(client, sdpHost) + if err != nil { + return err + } + } else { + _, err = CreateVMServer(s.KClient, serverRole, serverRole, sdp.PodAntiAffinity, sdp.NodeAffinity) + if err != nil { + return err + } } } } - s.Server, err = deployDeployment(client, sdp) - - s.ServerNodeInfo, _ = GetPodNodeInfo(client, sdp) - if !s.NodeLocal { - s.ClientNodeInfo, _ = GetPodNodeInfo(client, cdpAcross) - } - if err != nil { - return err - } - return nil -} - -func CreateVM(dynamicClient dynamic.Interface, namespace, vmName string) error { - gvr := schema.GroupVersionResource{ - Group: "kubevirt.io", - Version: "v1", - Resource: "virtualmachines", - } - - vm := &unstructured.Unstructured{ - Object: map[string]interface{}{ - "apiVersion": "kubevirt.io/v1", - "kind": "VirtualMachine", - "metadata": map[string]interface{}{ - "name": vmName, - "namespace": namespace, - }, - "spec": map[string]interface{}{ - "running": true, - "template": map[string]interface{}{ - "metadata": map[string]interface{}{ - "labels": map[string]interface{}{ - "kubevirt.io/domain": vmName, - }, - }, - "spec": map[string]interface{}{ - "domain": map[string]interface{}{ - "cpu": map[string]interface{}{ - "sockets": 2, - "cores": 2, - "threads": 1, - }, - "devices": map[string]interface{}{ - "disks": []interface{}{ - map[string]interface{}{ - "name": "disk0", - "disk": map[string]interface{}{ - "bus": "virtio", - }, - }, - }, - }, - "resources": map[string]interface{}{ - "requests": map[string]interface{}{ - "memory": "4096Mi", - "cpu": "500m", - }, - }, - }, - "volumes": []interface{}{ - map[string]interface{}{ - "name": "disk0", - "containerDisk": map[string]interface{}{ - "image": "kubevirt/fedora-cloud-container-disk-demo:latest", - }, - }, - map[string]interface{}{ - "name": "cloudinit", - "cloudInitNoCloud": map[string]interface{}{ - "userData": `#cloud-config - password: fedora - chpasswd: { expire: False } - runcmd: - - dnf install -y uperf iperf3 git ethtool`, - }, - }, - }, - }, - }, - }, - }, - } - - _, err := dynamicClient.Resource(gvr).Namespace(namespace).Create(context.TODO(), vm, metav1.CreateOptions{}) - if err != nil { - return fmt.Errorf("failed to create VirtualMachine: %v", err) + if !s.VM { + s.Server, err = deployDeployment(client, sdp) + if err != nil { + return err + } + s.ServerNodeInfo, _ = GetPodNodeInfo(client, sdp) + if !s.NodeLocal { + s.ClientNodeInfo, _ = GetPodNodeInfo(client, cdpAcross) + } + if err != nil { + return err + } + } else { + _, err = CreateVMServer(s.KClient, serverRole, serverRole, sdp.PodAntiAffinity, sdp.NodeAffinity) + if err != nil { + return err + } } - fmt.Printf("VirtualMachine %s created successfully in namespace %s\n", vmName, namespace) return nil } diff --git a/pkg/k8s/kubevirt.go b/pkg/k8s/kubevirt.go index d8c544e2..44e5b17e 100644 --- a/pkg/k8s/kubevirt.go +++ b/pkg/k8s/kubevirt.go @@ -7,7 +7,6 @@ import ( b64 "encoding/base64" - "github.com/cloud-bulldozer/k8s-netperf/pkg/config" kubevirtv1 "github.com/cloud-bulldozer/k8s-netperf/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1" log "github.com/cloud-bulldozer/k8s-netperf/pkg/logging" corev1 "k8s.io/api/core/v1" @@ -22,16 +21,6 @@ import ( v1 "kubevirt.io/api/core/v1" ) -func UpdateConfig(nc *[]config.Config, host string) []config.Config { - update := make([]config.Config, len(*nc)) - for _, cfg := range *nc { - cfg.VM = true - cfg.VMHost = host - update = append(update, cfg) - } - return update -} - func createCommService(client *kubernetes.Clientset, label map[string]string, name string) error { log.Infof("🚀 Creating service for %s in namespace %s", name, namespace) sc := client.CoreV1().Services(namespace) @@ -105,9 +94,13 @@ func exposeService(client *kubernetes.Clientset, dynamicClient *dynamic.DynamicC return host, nil } -func CreateVMClient(kclient *kubevirtv1.KubevirtV1Client, client *kubernetes.Clientset, dyn *dynamic.DynamicClient, name string) (string, error) { +func CreateVMClient(kclient *kubevirtv1.KubevirtV1Client, client *kubernetes.Clientset, + dyn *dynamic.DynamicClient, role string, name string, + podAff *corev1.PodAntiAffinity, + nodeAff *corev1.NodeAffinity) (string, error) { label := map[string]string{ - "app": fmt.Sprintf("%s", name), + "app": name, + "role": role, } dirname, err := os.UserHomeDir() if err != nil { @@ -130,7 +123,7 @@ chpasswd: { expire: False } runcmd: - dnf install -y uperf iperf3 git ethtool `, string(ssh)) - _, err = CreateVMI(kclient, name, label, b64.StdEncoding.EncodeToString([]byte(data))) + _, err = CreateVMI(kclient, name, label, b64.StdEncoding.EncodeToString([]byte(data)), *podAff, *nodeAff) if err != nil { return "", err } @@ -145,9 +138,12 @@ runcmd: return host, nil } -func CreateVMServer(client *kubevirtv1.KubevirtV1Client, name string) (*v1.VirtualMachineInstance, error) { +func CreateVMServer(client *kubevirtv1.KubevirtV1Client, name string, role string, + podAff corev1.PodAntiAffinity, + nodeAff corev1.NodeAffinity) (*v1.VirtualMachineInstance, error) { label := map[string]string{ - "app": fmt.Sprintf("%s", name), + "app": name, + "role": role, } dirname, err := os.UserHomeDir() if err != nil { @@ -172,10 +168,12 @@ runcmd: - uperf -s -v & - iperf3 -s & `, string(ssh)) - return CreateVMI(client, name, label, b64.StdEncoding.EncodeToString([]byte(data))) + return CreateVMI(client, name, label, b64.StdEncoding.EncodeToString([]byte(data)), podAff, nodeAff) } -func CreateVMI(client *kubevirtv1.KubevirtV1Client, name string, label map[string]string, b64data string) (*v1.VirtualMachineInstance, error) { +func CreateVMI(client *kubevirtv1.KubevirtV1Client, name string, label map[string]string, b64data string, + podAff corev1.PodAntiAffinity, + nodeAff corev1.NodeAffinity) (*v1.VirtualMachineInstance, error) { delSeconds := int64(0) mutliQ := true vmi, err := client.VirtualMachineInstances(namespace).Create(context.TODO(), &v1.VirtualMachineInstance{ @@ -189,6 +187,10 @@ func CreateVMI(client *kubevirtv1.KubevirtV1Client, name string, label map[strin Labels: label, }, Spec: v1.VirtualMachineInstanceSpec{ + Affinity: &k8sv1.Affinity{ + PodAntiAffinity: &podAff, + NodeAffinity: &nodeAff, + }, TerminationGracePeriodSeconds: &delSeconds, Domain: v1.DomainSpec{ Resources: v1.ResourceRequirements{ From 75310d46566395d38cd1885483c4ee4c392ca0f6 Mon Sep 17 00:00:00 2001 From: Joe Talerico aka rook Date: Fri, 30 Aug 2024 15:25:13 -0400 Subject: [PATCH 06/19] Adding ssh client Signed-off-by: Joe Talerico aka rook --- cmd/k8s-netperf/k8s-netperf.go | 2 ++ go.mod | 4 ++++ go.sum | 24 +++++++++++++++++++ pkg/k8s/kubernetes.go | 10 +++++--- pkg/k8s/kubevirt.go | 43 +++++++++++++++++++++++++++++++++- 5 files changed, 79 insertions(+), 4 deletions(-) diff --git a/cmd/k8s-netperf/k8s-netperf.go b/cmd/k8s-netperf/k8s-netperf.go index 97013900..ab722404 100644 --- a/cmd/k8s-netperf/k8s-netperf.go +++ b/cmd/k8s-netperf/k8s-netperf.go @@ -218,6 +218,8 @@ var rootCmd = &cobra.Command{ } } } + } else { + k8s.SSHConnect(&s) } if pavail { diff --git a/go.mod b/go.mod index d9764757..a09f2679 100644 --- a/go.mod +++ b/go.mod @@ -6,11 +6,14 @@ require ( github.com/aclements/go-moremath v0.0.0-20210112150236-f10218a38794 github.com/cloud-bulldozer/go-commons v1.0.16 github.com/google/uuid v1.3.0 + github.com/melbahja/goph v1.4.0 github.com/montanaflynn/stats v0.6.6 github.com/olekukonko/tablewriter v0.0.5 + github.com/pkg/sftp v1.13.5 github.com/prometheus/common v0.44.0 github.com/sirupsen/logrus v1.9.0 github.com/spf13/cobra v1.6.1 + golang.org/x/crypto v0.14.0 golang.org/x/text v0.13.0 gopkg.in/yaml.v3 v3.0.1 k8s.io/api v0.28.4 @@ -38,6 +41,7 @@ require ( github.com/inconshreveable/mousetrap v1.0.1 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/kr/fs v0.1.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-runewidth v0.0.9 // indirect github.com/moby/spdystream v0.2.0 // indirect diff --git a/go.sum b/go.sum index 0b48fb8e..df1f04e1 100644 --- a/go.sum +++ b/go.sum @@ -123,6 +123,8 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -141,6 +143,8 @@ github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/Qd github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/melbahja/goph v1.4.0 h1:z0PgDbBFe66lRYl3v5dGb9aFgPy0kotuQ37QOwSQFqs= +github.com/melbahja/goph v1.4.0/go.mod h1:uG+VfK2Dlhk+O32zFrRlc3kYKTlV6+BtvPWd/kK7U68= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= @@ -187,6 +191,8 @@ github.com/openshift/custom-resource-status v1.1.2 h1:C3DL44LEbvlbItfd8mT5jWrqPf github.com/openshift/custom-resource-status v1.1.2/go.mod h1:DB/Mf2oTeiAmVVX1gN+NEqweonAPY0TKUwADizj8+ZA= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.13.5 h1:a3RLUqkyjYRtBTZJZ1VRrKbN3zhuPLlUc3sphVz81go= +github.com/pkg/sftp v1.13.5/go.mod h1:wHDZ0IZX6JcBYRK1TH9bcVq8G7TLpVHYIGJRFnmPfxg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v1.15.1 h1:8tXpTmJbyH5lydzFPoxSIJ0J46jdh3tylbvM1xCv0LI= @@ -227,9 +233,15 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= +golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -238,6 +250,7 @@ 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.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -250,14 +263,18 @@ golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -269,6 +286,7 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ 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.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -292,11 +310,15 @@ golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -305,6 +327,7 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= @@ -322,6 +345,7 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.6-0.20210820212750-d4cc65f0b2ff/go.mod h1:YD9qOF0M9xpSpdWTBbzEl5e/RnCefISl8E5Noe10jFM= golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y= golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/pkg/k8s/kubernetes.go b/pkg/k8s/kubernetes.go index 5db9a0ff..50f16dd2 100644 --- a/pkg/k8s/kubernetes.go +++ b/pkg/k8s/kubernetes.go @@ -212,9 +212,9 @@ func BuildSUT(client *kubernetes.Clientset, s *config.PerfScenarios) error { } if !s.VM { s.Client, err = deployDeployment(client, cdp) - } - if err != nil { - return err + if err != nil { + return err + } } s.ClientNodeInfo, _ = GetPodNodeInfo(client, cdp) } @@ -315,6 +315,7 @@ func BuildSUT(client *kubernetes.Clientset, s *config.PerfScenarios) error { if err != nil { return err } + WaitForVMI(s.KClient, clientAcrossRole) } } if !s.VM { @@ -327,6 +328,7 @@ func BuildSUT(client *kubernetes.Clientset, s *config.PerfScenarios) error { if err != nil { return err } + WaitForVMI(s.KClient, clientAcrossRole) } } @@ -421,6 +423,7 @@ func BuildSUT(client *kubernetes.Clientset, s *config.PerfScenarios) error { if err != nil { return err } + WaitForVMI(s.KClient, serverRole) } } } @@ -441,6 +444,7 @@ func BuildSUT(client *kubernetes.Clientset, s *config.PerfScenarios) error { if err != nil { return err } + WaitForVMI(s.KClient, serverRole) } return nil diff --git a/pkg/k8s/kubevirt.go b/pkg/k8s/kubevirt.go index 44e5b17e..b1a54fc8 100644 --- a/pkg/k8s/kubevirt.go +++ b/pkg/k8s/kubevirt.go @@ -7,8 +7,11 @@ import ( b64 "encoding/base64" + "github.com/cloud-bulldozer/k8s-netperf/pkg/config" kubevirtv1 "github.com/cloud-bulldozer/k8s-netperf/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1" log "github.com/cloud-bulldozer/k8s-netperf/pkg/logging" + "github.com/melbahja/goph" + "golang.org/x/crypto/ssh" corev1 "k8s.io/api/core/v1" k8sv1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" @@ -21,6 +24,42 @@ import ( v1 "kubevirt.io/api/core/v1" ) +var ( + sshPort = uint(32022) +) + +func SSHConnect(conf *config.PerfScenarios) error { + dirname, err := os.UserHomeDir() + if err != nil { + return err + } + auth, err := goph.Key(fmt.Sprintf("%s/.ssh/id_rsa.pub", dirname), "") + if err != nil { + log.Fatal(err) + } + user := "fedora" + addr := conf.VMHost + + client, err := goph.NewConn(&goph.Config{ + User: user, + Addr: addr, + Port: sshPort, + Auth: auth, + Callback: ssh.InsecureIgnoreHostKey(), + }) + if err != nil { + return err + } + defer client.Close() + out, err := client.Run("ls /etc") + if err != nil { + return err + } + log.Info(string(out)) + + return nil +} + func createCommService(client *kubernetes.Clientset, label map[string]string, name string) error { log.Infof("🚀 Creating service for %s in namespace %s", name, namespace) sc := client.CoreV1().Services(namespace) @@ -34,7 +73,7 @@ func createCommService(client *kubernetes.Clientset, label map[string]string, na { Name: fmt.Sprintf("%s", name), Protocol: corev1.ProtocolTCP, - NodePort: 32022, + NodePort: int32(sshPort), TargetPort: intstr.Parse(fmt.Sprintf("%d", 22)), Port: 22, }, @@ -245,6 +284,7 @@ func CreateVMI(client *kubevirtv1.KubevirtV1Client, name string, label map[strin } func WaitForVMI(client *kubevirtv1.KubevirtV1Client, name string) error { + log.Infof("Wating for VMI (%s) to be in state running", name) vmw, err := client.VirtualMachineInstances(namespace).Watch(context.TODO(), metav1.ListOptions{}) if err != nil { return err @@ -256,6 +296,7 @@ func WaitForVMI(client *kubevirtv1.KubevirtV1Client, name string) error { return fmt.Errorf("Unable to watch VMI %s", name) } if d.Name == name { + log.Infof("Found in state (%s)", d.Status.Phase) if d.Status.Phase == "Running" { return nil } From 00dd2a35149c213054d2c0ca60f63facb821ef23 Mon Sep 17 00:00:00 2001 From: Joe Talerico aka rook Date: Tue, 3 Sep 2024 12:16:13 -0400 Subject: [PATCH 07/19] Adding retry to ssh Signed-off-by: Joe Talerico aka rook --- cmd/k8s-netperf/k8s-netperf.go | 6 +++++- pkg/k8s/kubernetes.go | 6 ++++-- pkg/k8s/kubevirt.go | 36 +++++++++++++++++++++++++++------- 3 files changed, 38 insertions(+), 10 deletions(-) diff --git a/cmd/k8s-netperf/k8s-netperf.go b/cmd/k8s-netperf/k8s-netperf.go index ab722404..7f078391 100644 --- a/cmd/k8s-netperf/k8s-netperf.go +++ b/cmd/k8s-netperf/k8s-netperf.go @@ -219,7 +219,11 @@ var rootCmd = &cobra.Command{ } } } else { - k8s.SSHConnect(&s) + log.Info("Connecting via ssh to the VMI") + err = k8s.SSHConnect(&s) + if err != nil { + log.Fatal(err) + } } if pavail { diff --git a/pkg/k8s/kubernetes.go b/pkg/k8s/kubernetes.go index 50f16dd2..46553de8 100644 --- a/pkg/k8s/kubernetes.go +++ b/pkg/k8s/kubernetes.go @@ -311,10 +311,11 @@ func BuildSUT(client *kubernetes.Clientset, s *config.PerfScenarios) error { return err } } else { - _, err := CreateVMClient(s.KClient, client, s.DClient, clientAcrossRole, clientAcrossRole, &cdpHostAcross.PodAntiAffinity, &cdpHostAcross.NodeAffinity) + host, err := CreateVMClient(s.KClient, client, s.DClient, clientAcrossRole, clientAcrossRole, &cdpHostAcross.PodAntiAffinity, &cdpHostAcross.NodeAffinity) if err != nil { return err } + s.VMHost = host WaitForVMI(s.KClient, clientAcrossRole) } } @@ -324,10 +325,11 @@ func BuildSUT(client *kubernetes.Clientset, s *config.PerfScenarios) error { return err } } else { - _, err := CreateVMClient(s.KClient, client, s.DClient, clientAcrossRole, clientAcrossRole, &cdpAcross.PodAntiAffinity, &cdpHostAcross.NodeAffinity) + host, err := CreateVMClient(s.KClient, client, s.DClient, clientAcrossRole, clientAcrossRole, &cdpAcross.PodAntiAffinity, &cdpHostAcross.NodeAffinity) if err != nil { return err } + s.VMHost = host WaitForVMI(s.KClient, clientAcrossRole) } diff --git a/pkg/k8s/kubevirt.go b/pkg/k8s/kubevirt.go index b1a54fc8..ca0ab859 100644 --- a/pkg/k8s/kubevirt.go +++ b/pkg/k8s/kubevirt.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "os" + "time" b64 "encoding/base64" @@ -26,29 +27,50 @@ import ( var ( sshPort = uint(32022) + retry = 30 ) +func connect(config *goph.Config) (*goph.Client, error) { + for i := 0; i < retry; i++ { + client, err := goph.NewConn(config) + if err != nil { + log.Debug("Waiting for ssh access to be available") + log.Debug(err) + time.Sleep(10 * time.Second) + continue + } else { + return client, nil + } + } + return nil, fmt.Errorf("Unable to connect via ssh after %d attempts", retry) +} + func SSHConnect(conf *config.PerfScenarios) error { - dirname, err := os.UserHomeDir() + dir, err := os.UserHomeDir() if err != nil { - return err + return fmt.Errorf("Unable to retrieve users homedir. %s", err) } - auth, err := goph.Key(fmt.Sprintf("%s/.ssh/id_rsa.pub", dirname), "") + key := fmt.Sprintf("%s/.ssh/id_rsa", dir) + keyd, err := os.ReadFile(key) + auth, err := goph.RawKey(string(keyd), "") if err != nil { - log.Fatal(err) + return fmt.Errorf("Unable to retrieve sshkey. Error : %s", err) } user := "fedora" addr := conf.VMHost + log.Infof("Attempting to connect with : %s@%s", user, addr) - client, err := goph.NewConn(&goph.Config{ + config := goph.Config{ User: user, Addr: addr, Port: sshPort, Auth: auth, Callback: ssh.InsecureIgnoreHostKey(), - }) + } + + client, err := connect(&config) if err != nil { - return err + return fmt.Errorf("Unable to connect via ssh. Error: %s", err) } defer client.Close() out, err := client.Run("ls /etc") From 927816407d5a868cfe60d5aa80585a182c33775f Mon Sep 17 00:00:00 2001 From: Joe Talerico aka rook Date: Tue, 3 Sep 2024 15:58:15 -0400 Subject: [PATCH 08/19] Adding virt in the drivers. Signed-off-by: Joe Talerico aka rook --- cmd/k8s-netperf/k8s-netperf.go | 53 +++++++-- pkg/config/config.go | 2 + pkg/drivers/driver.go | 2 +- pkg/drivers/iperf.go | 173 +++++++++++++++++++---------- pkg/drivers/netperf.go | 108 +++++++++++++----- pkg/drivers/uperf.go | 193 ++++++++++++++++++++++----------- pkg/k8s/kubernetes.go | 65 +++++++++++ pkg/k8s/kubevirt.go | 55 ++++++---- 8 files changed, 471 insertions(+), 180 deletions(-) diff --git a/cmd/k8s-netperf/k8s-netperf.go b/cmd/k8s-netperf/k8s-netperf.go index 7f078391..2975550d 100644 --- a/cmd/k8s-netperf/k8s-netperf.go +++ b/cmd/k8s-netperf/k8s-netperf.go @@ -207,12 +207,12 @@ var rootCmd = &cobra.Command{ var pr result.Data for _, driver := range requestedDrivers { if s.HostNetwork && !nc.Service { - pr = executeWorkload(nc, s, true, driver) + pr = executeWorkload(nc, s, true, driver, false) if len(pr.Profile) > 1 { sr.Results = append(sr.Results, pr) } } - pr = executeWorkload(nc, s, false, driver) + pr = executeWorkload(nc, s, false, driver, false) if len(pr.Profile) > 1 { sr.Results = append(sr.Results, pr) } @@ -220,18 +220,44 @@ var rootCmd = &cobra.Command{ } } else { log.Info("Connecting via ssh to the VMI") - err = k8s.SSHConnect(&s) + client, err := k8s.SSHConnect(&s) if err != nil { log.Fatal(err) } + s.SSHClient = client + for _, nc := range s.Configs { + // Determine the metric for the test + metric := string("OP/s") + if strings.Contains(nc.Profile, "STREAM") { + metric = "Mb/s" + } + nc.Metric = metric + nc.AcrossAZ = acrossAZ + // No need to run hostNetwork through Service. + var pr result.Data + for _, driver := range requestedDrivers { + if s.HostNetwork && !nc.Service { + pr = executeWorkload(nc, s, true, driver, true) + if len(pr.Profile) > 1 { + sr.Results = append(sr.Results, pr) + } + } + pr = executeWorkload(nc, s, false, driver, true) + if len(pr.Profile) > 1 { + sr.Results = append(sr.Results, pr) + } + } + } } if pavail { for i, npr := range sr.Results { - sr.Results[i].ClientMetrics, _ = metrics.QueryNodeCPU(npr.ClientNodeInfo, pcon, npr.StartTime, npr.EndTime) - sr.Results[i].ServerMetrics, _ = metrics.QueryNodeCPU(npr.ServerNodeInfo, pcon, npr.StartTime, npr.EndTime) - sr.Results[i].ClientPodCPU, _ = metrics.TopPodCPU(npr.ClientNodeInfo, pcon, npr.StartTime, npr.EndTime) - sr.Results[i].ServerPodCPU, _ = metrics.TopPodCPU(npr.ServerNodeInfo, pcon, npr.StartTime, npr.EndTime) + if len(npr.ClientNodeInfo.Hostname) > 0 && len(npr.ServerNodeInfo.Hostname) > 0 { + sr.Results[i].ClientMetrics, _ = metrics.QueryNodeCPU(npr.ClientNodeInfo, pcon, npr.StartTime, npr.EndTime) + sr.Results[i].ServerMetrics, _ = metrics.QueryNodeCPU(npr.ServerNodeInfo, pcon, npr.StartTime, npr.EndTime) + sr.Results[i].ClientPodCPU, _ = metrics.TopPodCPU(npr.ClientNodeInfo, pcon, npr.StartTime, npr.EndTime) + sr.Results[i].ServerPodCPU, _ = metrics.TopPodCPU(npr.ServerNodeInfo, pcon, npr.StartTime, npr.EndTime) + } } } @@ -332,14 +358,17 @@ func cleanup(client *kubernetes.Clientset) { } // executeWorkload executes the workload and returns the result data. -func executeWorkload(nc config.Config, s config.PerfScenarios, hostNet bool, driverName string) result.Data { +func executeWorkload(nc config.Config, + s config.PerfScenarios, + hostNet bool, + driverName string, virt bool) result.Data { serverIP := "" Client := s.Client var driver drivers.Driver if nc.Service { - if iperf3 { + if driverName == "iperf3" { serverIP = s.IperfService.Spec.ClusterIP - } else if uperf { + } else if driverName == "uperf" { serverIP = s.UperfService.Spec.ClusterIP } else { serverIP = s.NetperfService.Spec.ClusterIP @@ -387,7 +416,7 @@ func executeWorkload(nc config.Config, s config.PerfScenarios, hostNet bool, dri log.Warnf("Test %s is not supported with driver %s. Skipping.", nc.Profile, npr.Driver) return npr } - r, err := driver.Run(s.ClientSet, s.RestConfig, nc, Client, serverIP) + r, err := driver.Run(s.ClientSet, s.RestConfig, nc, Client, serverIP, &s) if err != nil { log.Fatal(err) } @@ -399,7 +428,7 @@ func executeWorkload(nc config.Config, s config.PerfScenarios, hostNet bool, dri // Retry the current test. for try < retry { log.Warn("Rerunning test.") - r, err := driver.Run(s.ClientSet, s.RestConfig, nc, Client, serverIP) + r, err := driver.Run(s.ClientSet, s.RestConfig, nc, Client, serverIP, &s) if err != nil { log.Error(err) continue diff --git a/pkg/config/config.go b/pkg/config/config.go index d4382b56..e40d08fa 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -6,6 +6,7 @@ import ( "regexp" kubevirtv1 "github.com/cloud-bulldozer/k8s-netperf/pkg/kubevirt/client-go/clientset/versioned/typed/core/v1" + "github.com/melbahja/goph" apiv1 "k8s.io/api/core/v1" log "github.com/cloud-bulldozer/k8s-netperf/pkg/logging" @@ -50,6 +51,7 @@ type PerfScenarios struct { ClientSet *kubernetes.Clientset KClient *kubevirtv1.KubevirtV1Client DClient *dynamic.DynamicClient + SSHClient *goph.Client } // Tests we will support in k8s-netperf diff --git a/pkg/drivers/driver.go b/pkg/drivers/driver.go index cd265c76..7359115a 100644 --- a/pkg/drivers/driver.go +++ b/pkg/drivers/driver.go @@ -12,7 +12,7 @@ import ( type Driver interface { IsTestSupported(string) bool - Run(c *kubernetes.Clientset, rc rest.Config, nc config.Config, client apiv1.PodList, serverIP string) (bytes.Buffer, error) + Run(c *kubernetes.Clientset, rc rest.Config, nc config.Config, client apiv1.PodList, serverIP string, perf *config.PerfScenarios) (bytes.Buffer, error) ParseResults(stdout *bytes.Buffer) (sample.Sample, error) } diff --git a/pkg/drivers/iperf.go b/pkg/drivers/iperf.go index e98652f3..5e99334b 100644 --- a/pkg/drivers/iperf.go +++ b/pkg/drivers/iperf.go @@ -6,6 +6,7 @@ import ( "fmt" "strconv" "strings" + "time" "encoding/json" @@ -51,7 +52,11 @@ func (i *iperf3) IsTestSupported(test string) bool { } // Run will invoke iperf3 in a client container -func (i *iperf3) Run(c *kubernetes.Clientset, rc rest.Config, nc config.Config, client apiv1.PodList, serverIP string) (bytes.Buffer, error) { +func (i *iperf3) Run(c *kubernetes.Clientset, + rc rest.Config, + nc config.Config, + client apiv1.PodList, + serverIP string, perf *config.PerfScenarios) (bytes.Buffer, error) { var stdout, stderr bytes.Buffer id := uuid.New() file := fmt.Sprintf("/tmp/iperf-%s", id.String()) @@ -85,68 +90,124 @@ func (i *iperf3) Run(c *kubernetes.Clientset, rc rest.Config, nc config.Config, } } log.Debug(cmd) - req := c.CoreV1().RESTClient(). - Post(). - Namespace(pod.Namespace). - Resource("pods"). - Name(pod.Name). - SubResource("exec"). - VersionedParams(&apiv1.PodExecOptions{ - Container: pod.Spec.Containers[0].Name, - Command: cmd, - Stdin: false, - Stdout: true, - Stderr: true, - TTY: true, - }, scheme.ParameterCodec) - exec, err := remotecommand.NewSPDYExecutor(&rc, "POST", req.URL()) - if err != nil { - return stdout, err - } - // Connect this process' std{in,out,err} to the remote shell process. - err = exec.StreamWithContext(context.Background(), remotecommand.StreamOptions{ - Stdin: nil, - Stdout: &stdout, - Stderr: &stderr, - }) - if err != nil { - return stdout, err + if !perf.VM { + req := c.CoreV1().RESTClient(). + Post(). + Namespace(pod.Namespace). + Resource("pods"). + Name(pod.Name). + SubResource("exec"). + VersionedParams(&apiv1.PodExecOptions{ + Container: pod.Spec.Containers[0].Name, + Command: cmd, + Stdin: false, + Stdout: true, + Stderr: true, + TTY: true, + }, scheme.ParameterCodec) + exec, err := remotecommand.NewSPDYExecutor(&rc, "POST", req.URL()) + if err != nil { + return stdout, err + } + // Connect this process' std{in,out,err} to the remote shell process. + err = exec.StreamWithContext(context.Background(), remotecommand.StreamOptions{ + Stdin: nil, + Stdout: &stdout, + Stderr: &stderr, + }) + if err != nil { + return stdout, err + } + } else { + retry := 3 + present := false + sshclient, err := k8s.SSHConnect(perf) + if err != nil { + return stdout, err + } + for i := 0; i <= retry; i++ { + log.Debug("⏰ Waiting for iperf3 to be present on VM") + _, err = sshclient.Run("until iperf3 -h; do sleep 30; done") + if err != nil { + time.Sleep(10 * time.Second) + continue + } else { + present = true + break + } + } + if !present { + sshclient.Close() + return stdout, fmt.Errorf("iperf3 binary is not present on the VM") + } + var stdout []byte + ran := false + for i := 0; i <= retry; i++ { + stdout, err = sshclient.Run(strings.Join(cmd[:], " ")) + if err != nil { + log.Debugf("Failed running command %s", err) + log.Debugf("⏰ Retrying iperf3 command -- cloud-init still finishing up") + time.Sleep(60 * time.Second) + continue + } else { + ran = true + break + } + } + sshclient.Close() + if !ran { + return *bytes.NewBuffer(stdout), fmt.Errorf("Unable to run iperf3") + } } //Empty buffer stdout = bytes.Buffer{} stderr = bytes.Buffer{} - req = c.CoreV1().RESTClient(). - Post(). - Namespace(pod.Namespace). - Resource("pods"). - Name(pod.Name). - SubResource("exec"). - VersionedParams(&apiv1.PodExecOptions{ - Container: pod.Spec.Containers[0].Name, - Command: []string{"cat", file}, - Stdin: false, - Stdout: true, - Stderr: true, - TTY: true, - }, scheme.ParameterCodec) - exec, err = remotecommand.NewSPDYExecutor(&rc, "POST", req.URL()) - if err != nil { - return stdout, err - } - // Connect this process' std{in,out,err} to the remote shell process. - err = exec.StreamWithContext(context.Background(), remotecommand.StreamOptions{ - Stdin: nil, - Stdout: &stdout, - Stderr: &stderr, - }) - if err != nil { - return stdout, err + if !perf.VM { + req := c.CoreV1().RESTClient(). + Post(). + Namespace(pod.Namespace). + Resource("pods"). + Name(pod.Name). + SubResource("exec"). + VersionedParams(&apiv1.PodExecOptions{ + Container: pod.Spec.Containers[0].Name, + Command: []string{"cat", file}, + Stdin: false, + Stdout: true, + Stderr: true, + TTY: true, + }, scheme.ParameterCodec) + exec, err := remotecommand.NewSPDYExecutor(&rc, "POST", req.URL()) + if err != nil { + return stdout, err + } + // Connect this process' std{in,out,err} to the remote shell process. + err = exec.StreamWithContext(context.Background(), remotecommand.StreamOptions{ + Stdin: nil, + Stdout: &stdout, + Stderr: &stderr, + }) + if err != nil { + return stdout, err + } + log.Debug(strings.TrimSpace(stdout.String())) + return stdout, nil + } else { + sshclient, err := k8s.SSHConnect(perf) + if err != nil { + return stdout, err + } + stdout, err := sshclient.Run(fmt.Sprintf("cat %s", file)) + if err != nil { + sshclient.Close() + return *bytes.NewBuffer(stdout), err + } + log.Debug(strings.TrimSpace(bytes.NewBuffer(stdout).String())) + sshclient.Close() + return *bytes.NewBuffer(stdout), nil } - - log.Debug(strings.TrimSpace(stdout.String())) - return stdout, nil } // ParseResults accepts the stdout from the execution of the benchmark. diff --git a/pkg/drivers/netperf.go b/pkg/drivers/netperf.go index ad172440..750c09ba 100644 --- a/pkg/drivers/netperf.go +++ b/pkg/drivers/netperf.go @@ -7,6 +7,7 @@ import ( "math" "strconv" "strings" + "time" apiv1 "k8s.io/api/core/v1" @@ -35,7 +36,7 @@ const omniOptions = "rt_latency,p99_latency,throughput,throughput_units,remote_r // Run will use the k8s client to run the netperf binary in the container image // it will return a bytes.Buffer of the stdout. -func (n *netperf) Run(c *kubernetes.Clientset, rc rest.Config, nc config.Config, client apiv1.PodList, serverIP string) (bytes.Buffer, error) { +func (n *netperf) Run(c *kubernetes.Clientset, rc rest.Config, nc config.Config, client apiv1.PodList, serverIP string, perf *config.PerfScenarios) (bytes.Buffer, error) { var stdout, stderr bytes.Buffer pod := client.Items[0] log.Debugf("🔥 Client (%s,%s) starting netperf against server: %s", pod.Name, pod.Status.PodIP, serverIP) @@ -49,35 +50,84 @@ func (n *netperf) Run(c *kubernetes.Clientset, rc rest.Config, nc config.Config, "-m", fmt.Sprint(nc.MessageSize), "-R", "1"} log.Debug(cmd) - req := c.CoreV1().RESTClient(). - Post(). - Namespace(pod.Namespace). - Resource("pods"). - Name(pod.Name). - SubResource("exec"). - VersionedParams(&apiv1.PodExecOptions{ - Container: pod.Spec.Containers[0].Name, - Command: cmd, - Stdin: false, - Stdout: true, - Stderr: true, - TTY: true, - }, scheme.ParameterCodec) - exec, err := remotecommand.NewSPDYExecutor(&rc, "POST", req.URL()) - if err != nil { - return stdout, err - } - // Connect this process' std{in,out,err} to the remote shell process. - err = exec.StreamWithContext(context.Background(), remotecommand.StreamOptions{ - Stdin: nil, - Stdout: &stdout, - Stderr: &stderr, - }) - if err != nil { - return stdout, err + if !perf.VM { + req := c.CoreV1().RESTClient(). + Post(). + Namespace(pod.Namespace). + Resource("pods"). + Name(pod.Name). + SubResource("exec"). + VersionedParams(&apiv1.PodExecOptions{ + Container: pod.Spec.Containers[0].Name, + Command: cmd, + Stdin: false, + Stdout: true, + Stderr: true, + TTY: true, + }, scheme.ParameterCodec) + exec, err := remotecommand.NewSPDYExecutor(&rc, "POST", req.URL()) + if err != nil { + return stdout, err + } + // Connect this process' std{in,out,err} to the remote shell process. + err = exec.StreamWithContext(context.Background(), remotecommand.StreamOptions{ + Stdin: nil, + Stdout: &stdout, + Stderr: &stderr, + }) + if err != nil { + return stdout, err + } + log.Debug(strings.TrimSpace(stdout.String())) + return stdout, nil + } else { + retry := 3 + present := false + sshclient, err := k8s.SSHConnect(perf) + if err != nil { + return stdout, err + } + for i := 0; i <= retry; i++ { + log.Debug("⏰ Waiting for netperf to be present on VM") + _, err = sshclient.Run("until which netperf; do sleep 30; done") + if err != nil { + time.Sleep(10 * time.Second) + continue + } else { + present = true + break + } + } + if !present { + sshclient.Close() + return stdout, fmt.Errorf("netperf binary is not present on the VM") + } + var stdout []byte + ran := false + for i := 0; i <= retry; i++ { + _, err = sshclient.Run(fmt.Sprintf("netperf -H %s -l 1 -- %s", serverIP, strconv.Itoa(k8s.NetperfServerDataPort))) + if err != nil { + log.Debugf("Failed running command %s", err) + log.Debugf("⏰ Retrying netperf command -- cloud-init still finishing up") + time.Sleep(60 * time.Second) + continue + } else { + ran = true + break + } + } + stdout, err = sshclient.Run(strings.Join(cmd[:], " ")) + if err != nil { + return *bytes.NewBuffer(stdout), fmt.Errorf("Failed running command %s", err) + } + sshclient.Close() + if !ran { + return *bytes.NewBuffer(stdout), fmt.Errorf("Unable to run iperf3") + } else { + log.Debug(bytes.NewBuffer(stdout)) + return *bytes.NewBuffer(stdout), nil + } } - log.Debug(strings.TrimSpace(stdout.String())) - return stdout, nil } // ParseResults accepts the stdout from the execution of the benchmark. It also needs diff --git a/pkg/drivers/uperf.go b/pkg/drivers/uperf.go index 60a1a160..93e99b85 100644 --- a/pkg/drivers/uperf.go +++ b/pkg/drivers/uperf.go @@ -7,6 +7,7 @@ import ( "regexp" "strconv" "strings" + "time" apiv1 "k8s.io/api/core/v1" @@ -51,7 +52,7 @@ func (u *uperf) IsTestSupported(test string) bool { // uperf needs "rr" or "stream" profiles which are config files passed to uperf command through -m option // We need to create these profiles based on the test using provided configuration -func createUperfProfile(c *kubernetes.Clientset, rc rest.Config, nc config.Config, pod apiv1.Pod, serverIP string) (string, error) { +func createUperfProfile(c *kubernetes.Clientset, rc rest.Config, nc config.Config, pod apiv1.Pod, serverIP string, perf *config.PerfScenarios) (string, error) { var stdout, stderr bytes.Buffer var fileContent string @@ -96,48 +97,65 @@ func createUperfProfile(c *kubernetes.Clientset, rc rest.Config, nc config.Confi filePath = fmt.Sprintf("/tmp/uperf-rr-%s-%d-%d", protocol, nc.MessageSize, nc.Parallelism) } - var cmd []string - uperfCmd := "echo '" + fileContent + "' > " + filePath - cmd = []string{"bash", "-c", uperfCmd} - //Empty buffer stdout = bytes.Buffer{} - req := c.CoreV1().RESTClient(). - Post(). - Namespace(pod.Namespace). - Resource("pods"). - Name(pod.Name). - SubResource("exec"). - VersionedParams(&apiv1.PodExecOptions{ - Container: pod.Spec.Containers[0].Name, - Command: cmd, - Stdin: false, - Stdout: true, - Stderr: true, - TTY: true, - }, scheme.ParameterCodec) - exec, err := remotecommand.NewSPDYExecutor(&rc, "POST", req.URL()) - if err != nil { - return filePath, err - } - // Connect this process' std{in,out,err} to the remote shell process. - err = exec.StreamWithContext(context.Background(), remotecommand.StreamOptions{ - Stdin: nil, - Stdout: &stdout, - Stderr: &stderr, - }) - if err != nil { - return filePath, err - } + if !perf.VM { + var cmd []string + uperfCmd := "echo '" + fileContent + "' > " + filePath + cmd = []string{"bash", "-c", uperfCmd} + req := c.CoreV1().RESTClient(). + Post(). + Namespace(pod.Namespace). + Resource("pods"). + Name(pod.Name). + SubResource("exec"). + VersionedParams(&apiv1.PodExecOptions{ + Container: pod.Spec.Containers[0].Name, + Command: cmd, + Stdin: false, + Stdout: true, + Stderr: true, + TTY: true, + }, scheme.ParameterCodec) + exec, err := remotecommand.NewSPDYExecutor(&rc, "POST", req.URL()) + if err != nil { + return filePath, err + } + // Connect this process' std{in,out,err} to the remote shell process. + err = exec.StreamWithContext(context.Background(), remotecommand.StreamOptions{ + Stdin: nil, + Stdout: &stdout, + Stderr: &stderr, + }) + if err != nil { + return filePath, err + } - log.Debug(strings.TrimSpace(stdout.String())) + log.Debug(strings.TrimSpace(stdout.String())) + return filePath, nil + } else { + + var cmd []string + uperfCmd := "echo '" + fileContent + "' > " + filePath + cmd = []string{uperfCmd} + sshclient, err := k8s.SSHConnect(perf) + if err != nil { + return filePath, err + } + log.Debug(strings.Join(cmd[:], " ")) + _, err = sshclient.Run(strings.Join(cmd[:], " ")) + if err != nil { + return filePath, err + } + sshclient.Close() + } return filePath, nil } // Run will invoke uperf in a client container -func (u *uperf) Run(c *kubernetes.Clientset, rc rest.Config, nc config.Config, client apiv1.PodList, serverIP string) (bytes.Buffer, error) { +func (u *uperf) Run(c *kubernetes.Clientset, rc rest.Config, nc config.Config, client apiv1.PodList, serverIP string, perf *config.PerfScenarios) (bytes.Buffer, error) { var stdout, stderr bytes.Buffer var exec remotecommand.Executor @@ -145,7 +163,8 @@ func (u *uperf) Run(c *kubernetes.Clientset, rc rest.Config, nc config.Config, c log.Debugf("🔥 Client (%s,%s) starting uperf against server: %s", pod.Name, pod.Status.PodIP, serverIP) config.Show(nc, u.driverName) - filePath, err := createUperfProfile(c, rc, nc, pod, serverIP) + log.Debug("Creating uperf configuration file") + filePath, err := createUperfProfile(c, rc, nc, pod, serverIP, perf) if err != nil { return stdout, err } @@ -157,35 +176,78 @@ func (u *uperf) Run(c *kubernetes.Clientset, rc rest.Config, nc config.Config, c cmd := []string{"uperf", "-v", "-a", "-R", "-i", "1", "-m", filePath, "-P", fmt.Sprint(k8s.UperfServerCtlPort)} log.Debug(cmd) - req := c.CoreV1().RESTClient(). - Post(). - Namespace(pod.Namespace). - Resource("pods"). - Name(pod.Name). - SubResource("exec"). - VersionedParams(&apiv1.PodExecOptions{ - Container: pod.Spec.Containers[0].Name, - Command: cmd, - Stdin: false, - Stdout: true, - Stderr: true, - TTY: true, - }, scheme.ParameterCodec) - exec, err = remotecommand.NewSPDYExecutor(&rc, "POST", req.URL()) - if err != nil { - return stdout, err - } - // Connect this process' std{in,out,err} to the remote shell process. - err = exec.StreamWithContext(context.Background(), remotecommand.StreamOptions{ - Stdin: nil, - Stdout: &stdout, - Stderr: &stderr, - }) - if err != nil { - return stdout, err + if !perf.VM { + req := c.CoreV1().RESTClient(). + Post(). + Namespace(pod.Namespace). + Resource("pods"). + Name(pod.Name). + SubResource("exec"). + VersionedParams(&apiv1.PodExecOptions{ + Container: pod.Spec.Containers[0].Name, + Command: cmd, + Stdin: false, + Stdout: true, + Stderr: true, + TTY: true, + }, scheme.ParameterCodec) + exec, err = remotecommand.NewSPDYExecutor(&rc, "POST", req.URL()) + if err != nil { + return stdout, err + } + // Connect this process' std{in,out,err} to the remote shell process. + err = exec.StreamWithContext(context.Background(), remotecommand.StreamOptions{ + Stdin: nil, + Stdout: &stdout, + Stderr: &stderr, + }) + if err != nil { + return stdout, err + } + return stdout, nil + } else { + retry := 3 + present := false + sshclient, err := k8s.SSHConnect(perf) + if err != nil { + return stdout, err + } + for i := 0; i <= retry; i++ { + log.Debug("⏰ Waiting for uperf to be present on VM") + _, err = sshclient.Run("until uperf -h; do sleep 30; done") + if err != nil { + time.Sleep(10 * time.Second) + continue + } else { + present = true + break + } + } + if !present { + sshclient.Close() + return stdout, fmt.Errorf("uperf binary is not present on the VM") + } + var stdout []byte + ran := false + for i := 0; i <= retry; i++ { + stdout, err = sshclient.Run(strings.Join(cmd[:], " ")) + if err != nil { + log.Debugf("Failed running command %s", err) + log.Debugf("⏰ Retrying uperf command -- cloud-init still finishing up") + time.Sleep(60 * time.Second) + continue + } else { + ran = true + break + } + } + sshclient.Close() + if !ran { + return *bytes.NewBuffer(stdout), fmt.Errorf("Unable to run uperf") + } else { + return *bytes.NewBuffer(stdout), nil + } } - - return stdout, nil } // ParseResults accepts the stdout from the execution of the benchmark. @@ -197,6 +259,11 @@ func (u *uperf) ParseResults(stdout *bytes.Buffer) (sample.Sample, error) { transactions := regexp.MustCompile(`timestamp_ms:(.*) name:Txn2 nr_bytes:(.*) nr_ops:(.*)\r`).FindAllStringSubmatch(stdout.String(), -1) + // VM output does not have the \r. + if len(transactions) < 1 { + transactions = regexp.MustCompile(`timestamp_ms:(.*) name:Txn2 nr_bytes:(.*) nr_ops:(.*)`).FindAllStringSubmatch(stdout.String(), -1) + } + var prevTimestamp, normLtcy float64 var prevBytes, prevOps, normOps float64 var byteSummary, latSummary, opSummary []float64 diff --git a/pkg/k8s/kubernetes.go b/pkg/k8s/kubernetes.go index 46553de8..4dfb95b0 100644 --- a/pkg/k8s/kubernetes.go +++ b/pkg/k8s/kubernetes.go @@ -317,6 +317,11 @@ func BuildSUT(client *kubernetes.Clientset, s *config.PerfScenarios) error { } s.VMHost = host WaitForVMI(s.KClient, clientAcrossRole) + s.ClientAcross, err = GetNakedPods(s.ClientSet, fmt.Sprintf("app=%s", clientAcrossRole)) + if err != nil { + return err + } + s.ClientNodeInfo, _ = GetNakedPodNodeInfo(client, fmt.Sprintf("app=%s", clientAcrossRole)) } } if !s.VM { @@ -331,6 +336,11 @@ func BuildSUT(client *kubernetes.Clientset, s *config.PerfScenarios) error { } s.VMHost = host WaitForVMI(s.KClient, clientAcrossRole) + s.ClientAcross, err = GetNakedPods(s.ClientSet, fmt.Sprintf("app=%s", clientAcrossRole)) + if err != nil { + return err + } + s.ClientNodeInfo, _ = GetNakedPodNodeInfo(client, fmt.Sprintf("app=%s", clientAcrossRole)) } } @@ -426,6 +436,11 @@ func BuildSUT(client *kubernetes.Clientset, s *config.PerfScenarios) error { return err } WaitForVMI(s.KClient, serverRole) + s.ServerHost, err = GetNakedPods(s.ClientSet, fmt.Sprintf("app=%s", serverRole)) + if err != nil { + return err + } + s.ServerNodeInfo, _ = GetNakedPodNodeInfo(client, fmt.Sprintf("app=%s", serverRole)) } } } @@ -447,6 +462,11 @@ func BuildSUT(client *kubernetes.Clientset, s *config.PerfScenarios) error { return err } WaitForVMI(s.KClient, serverRole) + s.Server, err = GetNakedPods(s.ClientSet, fmt.Sprintf("app=%s", serverRole)) + if err != nil { + return err + } + s.ServerNodeInfo, _ = GetNakedPodNodeInfo(client, fmt.Sprintf("app=%s", serverRole)) } return nil @@ -615,6 +635,7 @@ func CreateDeployment(dp DeploymentParams, client *kubernetes.Clientset) (*appsv // GetNodeLabels Return Labels for a specific node func GetNodeLabels(c *kubernetes.Clientset, node string) (map[string]string, error) { + log.Debugf("Looking for Node labels for node - %s", node) nodeInfo, err := c.CoreV1().Nodes().Get(context.TODO(), node, metav1.GetOptions{}) if err != nil { return nil, err @@ -650,6 +671,29 @@ func GetPodNodeInfo(c *kubernetes.Clientset, dp DeploymentParams) (metrics.NodeI return info, nil } +// GetNakedPodNodeInfo collects the node information for a specific pod +func GetNakedPodNodeInfo(c *kubernetes.Clientset, label string) (metrics.NodeInfo, error) { + var info metrics.NodeInfo + listOpt := metav1.ListOptions{ + LabelSelector: label, + } + pods, err := c.CoreV1().Pods(namespace).List(context.TODO(), listOpt) + if err != nil { + return info, fmt.Errorf("❌ Failure to capture pods: %v", err) + } + for pod := range pods.Items { + p := pods.Items[pod] + if pods.Items[pod].DeletionTimestamp != nil { + continue + } else { + info.IP = p.Status.HostIP + info.Hostname = p.Spec.NodeName + } + } + log.Debugf("Machine with lablel %s is Running on %s with IP %s", label, info.Hostname, info.IP) + return info, nil +} + // GetPods searches for a specific set of pods from DeploymentParms // It returns a PodList if the deployment is found. // NOTE : Since we can update the replicas to be > 1, is why I return a PodList. @@ -677,6 +721,27 @@ func GetPods(c *kubernetes.Clientset, dp DeploymentParams) (corev1.PodList, erro return npl, nil } +func GetNakedPods(c *kubernetes.Clientset, label string) (corev1.PodList, error) { + npl := corev1.PodList{} + listOpt := metav1.ListOptions{ + LabelSelector: label, + } + log.Infof("Looking for pods with label %s", fmt.Sprint(label)) + pods, err := c.CoreV1().Pods(namespace).List(context.TODO(), listOpt) + if err != nil { + return npl, fmt.Errorf("❌ Failure to capture pods: %v", err) + } + for pod := range pods.Items { + if pods.Items[pod].DeletionTimestamp != nil { + continue + } else { + npl.Items = append(npl.Items, pods.Items[pod]) + } + } + return npl, nil + +} + // CreateService will build a k8s service func CreateService(sp ServiceParams, client *kubernetes.Clientset) (*corev1.Service, error) { s, err := client.CoreV1().Services(sp.Namespace).Get(context.TODO(), sp.Name, metav1.GetOptions{}) diff --git a/pkg/k8s/kubevirt.go b/pkg/k8s/kubevirt.go index ca0ab859..f2df1095 100644 --- a/pkg/k8s/kubevirt.go +++ b/pkg/k8s/kubevirt.go @@ -45,20 +45,20 @@ func connect(config *goph.Config) (*goph.Client, error) { return nil, fmt.Errorf("Unable to connect via ssh after %d attempts", retry) } -func SSHConnect(conf *config.PerfScenarios) error { +func SSHConnect(conf *config.PerfScenarios) (*goph.Client, error) { dir, err := os.UserHomeDir() if err != nil { - return fmt.Errorf("Unable to retrieve users homedir. %s", err) + return nil, fmt.Errorf("Unable to retrieve users homedir. %s", err) } key := fmt.Sprintf("%s/.ssh/id_rsa", dir) keyd, err := os.ReadFile(key) auth, err := goph.RawKey(string(keyd), "") if err != nil { - return fmt.Errorf("Unable to retrieve sshkey. Error : %s", err) + return nil, fmt.Errorf("Unable to retrieve sshkey. Error : %s", err) } user := "fedora" addr := conf.VMHost - log.Infof("Attempting to connect with : %s@%s", user, addr) + log.Debugf("Attempting to connect with : %s@%s", user, addr) config := goph.Config{ User: user, @@ -70,16 +70,10 @@ func SSHConnect(conf *config.PerfScenarios) error { client, err := connect(&config) if err != nil { - return fmt.Errorf("Unable to connect via ssh. Error: %s", err) + return nil, fmt.Errorf("Unable to connect via ssh. Error: %s", err) } - defer client.Close() - out, err := client.Run("ls /etc") - if err != nil { - return err - } - log.Info(string(out)) - return nil + return client, nil } func createCommService(client *kubernetes.Clientset, label map[string]string, name string) error { @@ -182,7 +176,19 @@ ssh_deletekeys: false password: fedora chpasswd: { expire: False } runcmd: - - dnf install -y uperf iperf3 git ethtool + - export HOME=/home/fedora + - dnf install -y --nodocs uperf iperf3 git ethtool automake gcc bc lksctp-tools-devel texinfo --enablerepo=* + - git clone https://github.com/HewlettPackard/netperf + - cd netperf + - git reset --hard 3bc455b23f901dae377ca0a558e1e32aa56b31c4 + - curl -o netperf.diff https://raw.githubusercontent.com/cloud-bulldozer/k8s-netperf/main/containers/netperf.diff + - git apply netperf.diff + - ./autogen.sh + - ./configure --enable-sctp=yes --enable-demo=yes + - make && make install + - cd + - curl -o /usr/bin/super-netperf https://raw.githubusercontent.com/cloud-bulldozer/k8s-netperf/main/containers/super-netperf + - chmod 0777 /usr/bin/super-netperf `, string(ssh)) _, err = CreateVMI(kclient, name, label, b64.StdEncoding.EncodeToString([]byte(data)), *podAff, *nodeAff) if err != nil { @@ -225,10 +231,21 @@ ssh_deletekeys: false password: fedora chpasswd: { expire: False } runcmd: - - dnf install -y uperf iperf3 git ethtool - - uperf -s -v & - - iperf3 -s & -`, string(ssh)) + - dnf install -y --nodocs uperf iperf3 git ethtool + - dnf install -y --nodocs automake gcc bc lksctp-tools-devel texinfo --enablerepo=* + - git clone https://github.com/HewlettPackard/netperf + - cd netperf + - git reset --hard 3bc455b23f901dae377ca0a558e1e32aa56b31c4 + - curl -o netperf.diff https://raw.githubusercontent.com/cloud-bulldozer/k8s-netperf/main/containers/netperf.diff + - git apply netperf.diff + - ./autogen.sh + - ./configure --enable-sctp=yes --enable-demo=yes + - make && make install + - cd + - uperf -s -v -P %d & + - iperf3 -s -p %d & + - netserver & +`, string(ssh), UperfServerCtlPort, IperfServerCtlPort) return CreateVMI(client, name, label, b64.StdEncoding.EncodeToString([]byte(data)), podAff, nodeAff) } @@ -306,7 +323,7 @@ func CreateVMI(client *kubevirtv1.KubevirtV1Client, name string, label map[strin } func WaitForVMI(client *kubevirtv1.KubevirtV1Client, name string) error { - log.Infof("Wating for VMI (%s) to be in state running", name) + log.Infof("⏰ Wating for VMI (%s) to be in state running", name) vmw, err := client.VirtualMachineInstances(namespace).Watch(context.TODO(), metav1.ListOptions{}) if err != nil { return err @@ -318,7 +335,7 @@ func WaitForVMI(client *kubevirtv1.KubevirtV1Client, name string) error { return fmt.Errorf("Unable to watch VMI %s", name) } if d.Name == name { - log.Infof("Found in state (%s)", d.Status.Phase) + log.Debugf("Found in state (%s)", d.Status.Phase) if d.Status.Phase == "Running" { return nil } From 133e2b9899f8253dc301edd2dfb624366fb0f560 Mon Sep 17 00:00:00 2001 From: Joe Talerico aka rook Date: Thu, 5 Sep 2024 14:14:45 -0400 Subject: [PATCH 09/19] Fix Driver Signed-off-by: Joe Talerico aka rook --- pkg/drivers/driver.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/drivers/driver.go b/pkg/drivers/driver.go index 7359115a..1ea3327c 100644 --- a/pkg/drivers/driver.go +++ b/pkg/drivers/driver.go @@ -13,7 +13,7 @@ import ( type Driver interface { IsTestSupported(string) bool Run(c *kubernetes.Clientset, rc rest.Config, nc config.Config, client apiv1.PodList, serverIP string, perf *config.PerfScenarios) (bytes.Buffer, error) - ParseResults(stdout *bytes.Buffer) (sample.Sample, error) + ParseResults(stdout *bytes.Buffer, nc config.Config) (sample.Sample, error) } type netperf struct { From 08c96543bb2db4f848d9443c43639aea32779d54 Mon Sep 17 00:00:00 2001 From: Joe Talerico aka rook Date: Thu, 5 Sep 2024 15:01:50 -0400 Subject: [PATCH 10/19] Fix UDP_STREAM Signed-off-by: Joe Talerico aka rook --- pkg/drivers/netperf.go | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/pkg/drivers/netperf.go b/pkg/drivers/netperf.go index 63443d30..453b37ad 100644 --- a/pkg/drivers/netperf.go +++ b/pkg/drivers/netperf.go @@ -49,13 +49,19 @@ func (n *netperf) Run(c *kubernetes.Clientset, rc rest.Config, nc config.Config, "-k", fmt.Sprint(omniOptions)} var additionalOptions []string if strings.Contains(nc.Profile, "STREAM") { - additionalOptions = []string { - "-m", fmt.Sprint(nc.MessageSize)} + if strings.Contains(nc.Profile, "UDP") { + additionalOptions = []string{ + "-m", fmt.Sprint(nc.MessageSize), + "-R", "1"} + } else { + additionalOptions = []string{ + "-m", fmt.Sprint(nc.MessageSize)} + } } else { - additionalOptions = []string { + additionalOptions = []string{ "-r", fmt.Sprint(nc.MessageSize, ",", nc.MessageSize)} if strings.Contains(nc.Profile, "TCP_RR") && (nc.Burst > 0) { - burst := []string {"-b", fmt.Sprint(nc.Burst)} + burst := []string{"-b", fmt.Sprint(nc.Burst)} additionalOptions = append(additionalOptions, burst...) } } From 324462028113f6e007b54b2bb2a7fa4b9b90201a Mon Sep 17 00:00:00 2001 From: Joe Talerico aka rook Date: Thu, 5 Sep 2024 15:16:42 -0400 Subject: [PATCH 11/19] Going to Go1.19 Signed-off-by: Joe Talerico aka rook --- go.mod | 4 ++-- go.sum | 16 ---------------- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/go.mod b/go.mod index a09f2679..4b4517df 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/cloud-bulldozer/k8s-netperf -go 1.23 +go 1.19 require ( github.com/aclements/go-moremath v0.0.0-20210112150236-f10218a38794 @@ -9,7 +9,6 @@ require ( github.com/melbahja/goph v1.4.0 github.com/montanaflynn/stats v0.6.6 github.com/olekukonko/tablewriter v0.0.5 - github.com/pkg/sftp v1.13.5 github.com/prometheus/common v0.44.0 github.com/sirupsen/logrus v1.9.0 github.com/spf13/cobra v1.6.1 @@ -52,6 +51,7 @@ require ( github.com/openshift/api v0.0.0-20230503133300-8bbcb7ca7183 // indirect github.com/openshift/custom-resource-status v1.1.2 // indirect github.com/pkg/errors v0.9.1 // indirect + github.com/pkg/sftp v1.13.5 // indirect github.com/prometheus/client_golang v1.15.1 // indirect github.com/spf13/pflag v1.0.5 // indirect golang.org/x/net v0.17.0 // indirect diff --git a/go.sum b/go.sum index df1f04e1..6613364c 100644 --- a/go.sum +++ b/go.sum @@ -6,14 +6,11 @@ github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdko github.com/aclements/go-moremath v0.0.0-20210112150236-f10218a38794 h1:xlwdaKcTNVW4PtpQb8aKA4Pjy0CdJHEqvFbAnvR5m2g= github.com/aclements/go-moremath v0.0.0-20210112150236-f10218a38794/go.mod h1:7e+I0LQFUI9AXWxOfsQROs9xPhoJtbsyWcjJqDd4KPY= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/aws/aws-sdk-go v1.42.27/go.mod h1:OGr6lGMAKGlG9CVrYnWYDKIyb829c6EVBRjxqjmPepc= 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/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= @@ -64,7 +61,6 @@ github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/ github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -98,7 +94,6 @@ github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -117,7 +112,6 @@ github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfC github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= -github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= @@ -129,7 +123,6 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -142,7 +135,6 @@ github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJ github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= -github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/melbahja/goph v1.4.0 h1:z0PgDbBFe66lRYl3v5dGb9aFgPy0kotuQ37QOwSQFqs= github.com/melbahja/goph v1.4.0/go.mod h1:uG+VfK2Dlhk+O32zFrRlc3kYKTlV6+BtvPWd/kK7U68= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= @@ -160,7 +152,6 @@ github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8m github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= @@ -175,14 +166,12 @@ github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/ginkgo/v2 v2.9.4 h1:xR7vG4IXt5RWx6FfIjyAtsoMAtnc3C/rFXBBd2AjZwE= -github.com/onsi/ginkgo/v2 v2.9.4/go.mod h1:gCQYp2Q+kSoIj7ykSVb9nskRSsR6PUj4AiLywzIhbKM= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= -github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= github.com/opensearch-project/opensearch-go v1.1.0 h1:eG5sh3843bbU1itPRjA9QXbxcg8LaZ+DjEzQH9aLN3M= github.com/opensearch-project/opensearch-go v1.1.0/go.mod h1:+6/XHCuTH+fwsMJikZEWsucZ4eZMma3zNSeLrTtVGbo= github.com/openshift/api v0.0.0-20230503133300-8bbcb7ca7183 h1:t/CahSnpqY46sQR01SoS+Jt0jtjgmhgE6lFmRnO4q70= @@ -199,13 +188,10 @@ github.com/prometheus/client_golang v1.15.1 h1:8tXpTmJbyH5lydzFPoxSIJ0J46jdh3tyl github.com/prometheus/client_golang v1.15.1/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= -github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= -github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= @@ -227,7 +213,6 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= @@ -347,7 +332,6 @@ golang.org/x/tools v0.1.6-0.20210820212750-d4cc65f0b2ff/go.mod h1:YD9qOF0M9xpSpd golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y= -golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= 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= From 73cfadbd2646be4ef6571fa4e44236ad529c9681 Mon Sep 17 00:00:00 2001 From: Joe Talerico aka rook Date: Thu, 5 Sep 2024 15:35:54 -0400 Subject: [PATCH 12/19] Address linting Signed-off-by: Joe Talerico aka rook --- pkg/k8s/kubernetes.go | 20 ++++++++++++++++---- pkg/k8s/kubevirt.go | 5 ++++- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/pkg/k8s/kubernetes.go b/pkg/k8s/kubernetes.go index 4dfb95b0..f84edff7 100644 --- a/pkg/k8s/kubernetes.go +++ b/pkg/k8s/kubernetes.go @@ -316,7 +316,10 @@ func BuildSUT(client *kubernetes.Clientset, s *config.PerfScenarios) error { return err } s.VMHost = host - WaitForVMI(s.KClient, clientAcrossRole) + err = WaitForVMI(s.KClient, clientAcrossRole) + if err != nil { + return err + } s.ClientAcross, err = GetNakedPods(s.ClientSet, fmt.Sprintf("app=%s", clientAcrossRole)) if err != nil { return err @@ -335,7 +338,10 @@ func BuildSUT(client *kubernetes.Clientset, s *config.PerfScenarios) error { return err } s.VMHost = host - WaitForVMI(s.KClient, clientAcrossRole) + err = WaitForVMI(s.KClient, clientAcrossRole) + if err != nil { + return err + } s.ClientAcross, err = GetNakedPods(s.ClientSet, fmt.Sprintf("app=%s", clientAcrossRole)) if err != nil { return err @@ -435,7 +441,10 @@ func BuildSUT(client *kubernetes.Clientset, s *config.PerfScenarios) error { if err != nil { return err } - WaitForVMI(s.KClient, serverRole) + err = WaitForVMI(s.KClient, serverRole) + if err != nil { + return err + } s.ServerHost, err = GetNakedPods(s.ClientSet, fmt.Sprintf("app=%s", serverRole)) if err != nil { return err @@ -461,7 +470,10 @@ func BuildSUT(client *kubernetes.Clientset, s *config.PerfScenarios) error { if err != nil { return err } - WaitForVMI(s.KClient, serverRole) + err = WaitForVMI(s.KClient, serverRole) + if err != nil { + return err + } s.Server, err = GetNakedPods(s.ClientSet, fmt.Sprintf("app=%s", serverRole)) if err != nil { return err diff --git a/pkg/k8s/kubevirt.go b/pkg/k8s/kubevirt.go index f2df1095..163c3457 100644 --- a/pkg/k8s/kubevirt.go +++ b/pkg/k8s/kubevirt.go @@ -52,6 +52,9 @@ func SSHConnect(conf *config.PerfScenarios) (*goph.Client, error) { } key := fmt.Sprintf("%s/.ssh/id_rsa", dir) keyd, err := os.ReadFile(key) + if err != nil { + return nil, fmt.Errorf("Unable to read key. Error : %s", err) + } auth, err := goph.RawKey(string(keyd), "") if err != nil { return nil, fmt.Errorf("Unable to retrieve sshkey. Error : %s", err) @@ -87,7 +90,7 @@ func createCommService(client *kubernetes.Clientset, label map[string]string, na Spec: corev1.ServiceSpec{ Ports: []corev1.ServicePort{ { - Name: fmt.Sprintf("%s", name), + Name: name, Protocol: corev1.ProtocolTCP, NodePort: int32(sshPort), TargetPort: intstr.Parse(fmt.Sprintf("%d", 22)), From 105e2471d78797d68d36aef8cfcc682e754988f5 Mon Sep 17 00:00:00 2001 From: Joe Talerico aka rook Date: Fri, 6 Sep 2024 15:56:34 -0400 Subject: [PATCH 13/19] Addressing Raul's comments Signed-off-by: Joe Talerico aka rook --- pkg/k8s/kubernetes.go | 87 +++++++++++++++++++++++++------------------ pkg/k8s/kubevirt.go | 14 +++---- 2 files changed, 56 insertions(+), 45 deletions(-) diff --git a/pkg/k8s/kubernetes.go b/pkg/k8s/kubernetes.go index f84edff7..41d09bdc 100644 --- a/pkg/k8s/kubernetes.go +++ b/pkg/k8s/kubernetes.go @@ -3,6 +3,7 @@ package k8s import ( "context" "fmt" + "strings" "github.com/cloud-bulldozer/k8s-netperf/pkg/config" log "github.com/cloud-bulldozer/k8s-netperf/pkg/logging" @@ -311,20 +312,10 @@ func BuildSUT(client *kubernetes.Clientset, s *config.PerfScenarios) error { return err } } else { - host, err := CreateVMClient(s.KClient, client, s.DClient, clientAcrossRole, clientAcrossRole, &cdpHostAcross.PodAntiAffinity, &cdpHostAcross.NodeAffinity) + err = launchClientVM(s, clientAcrossRole, &cdpAcross.PodAntiAffinity, &cdpHostAcross.NodeAffinity) if err != nil { return err } - s.VMHost = host - err = WaitForVMI(s.KClient, clientAcrossRole) - if err != nil { - return err - } - s.ClientAcross, err = GetNakedPods(s.ClientSet, fmt.Sprintf("app=%s", clientAcrossRole)) - if err != nil { - return err - } - s.ClientNodeInfo, _ = GetNakedPodNodeInfo(client, fmt.Sprintf("app=%s", clientAcrossRole)) } } if !s.VM { @@ -333,20 +324,10 @@ func BuildSUT(client *kubernetes.Clientset, s *config.PerfScenarios) error { return err } } else { - host, err := CreateVMClient(s.KClient, client, s.DClient, clientAcrossRole, clientAcrossRole, &cdpAcross.PodAntiAffinity, &cdpHostAcross.NodeAffinity) - if err != nil { - return err - } - s.VMHost = host - err = WaitForVMI(s.KClient, clientAcrossRole) - if err != nil { - return err - } - s.ClientAcross, err = GetNakedPods(s.ClientSet, fmt.Sprintf("app=%s", clientAcrossRole)) + err = launchClientVM(s, clientAcrossRole, &cdpAcross.PodAntiAffinity, &cdpHostAcross.NodeAffinity) if err != nil { return err } - s.ClientNodeInfo, _ = GetNakedPodNodeInfo(client, fmt.Sprintf("app=%s", clientAcrossRole)) } } @@ -437,19 +418,10 @@ func BuildSUT(client *kubernetes.Clientset, s *config.PerfScenarios) error { return err } } else { - _, err = CreateVMServer(s.KClient, serverRole, serverRole, sdp.PodAntiAffinity, sdp.NodeAffinity) + err = launchServerVM(s, serverRole, &sdp.PodAntiAffinity, &sdp.NodeAffinity) if err != nil { return err } - err = WaitForVMI(s.KClient, serverRole) - if err != nil { - return err - } - s.ServerHost, err = GetNakedPods(s.ClientSet, fmt.Sprintf("app=%s", serverRole)) - if err != nil { - return err - } - s.ServerNodeInfo, _ = GetNakedPodNodeInfo(client, fmt.Sprintf("app=%s", serverRole)) } } } @@ -466,21 +438,63 @@ func BuildSUT(client *kubernetes.Clientset, s *config.PerfScenarios) error { return err } } else { - _, err = CreateVMServer(s.KClient, serverRole, serverRole, sdp.PodAntiAffinity, sdp.NodeAffinity) + err = launchServerVM(s, serverRole, &sdp.PodAntiAffinity, &sdp.NodeAffinity) if err != nil { return err } - err = WaitForVMI(s.KClient, serverRole) + } + + return nil +} + +// launchServerVM will create the ServerVM with the specific node and pod affinity. +func launchServerVM(perf *config.PerfScenarios, name string, podAff *corev1.PodAntiAffinity, nodeAff *corev1.NodeAffinity) error { + _, err := CreateVMServer(perf.KClient, serverRole, serverRole, *podAff, *nodeAff) + if err != nil { + return err + } + err = WaitForVMI(perf.KClient, serverRole) + if err != nil { + return err + } + if strings.Contains(name, "host") { + perf.ServerHost, err = GetNakedPods(perf.ClientSet, fmt.Sprintf("app=%s", serverRole)) if err != nil { return err } - s.Server, err = GetNakedPods(s.ClientSet, fmt.Sprintf("app=%s", serverRole)) + } else { + perf.Server, err = GetNakedPods(perf.ClientSet, fmt.Sprintf("app=%s", serverRole)) if err != nil { return err } - s.ServerNodeInfo, _ = GetNakedPodNodeInfo(client, fmt.Sprintf("app=%s", serverRole)) } + perf.ServerNodeInfo, _ = GetNakedPodNodeInfo(perf.ClientSet, fmt.Sprintf("app=%s", serverRole)) + return nil +} +// launchClientVM will create the ClientVM with the specific node and pod affinity. +func launchClientVM(perf *config.PerfScenarios, name string, podAff *corev1.PodAntiAffinity, nodeAff *corev1.NodeAffinity) error { + host, err := CreateVMClient(perf.KClient, perf.ClientSet, perf.DClient, name, podAff, nodeAff) + if err != nil { + return err + } + perf.VMHost = host + err = WaitForVMI(perf.KClient, name) + if err != nil { + return err + } + if strings.Contains(name, "host") { + perf.ClientHost, err = GetNakedPods(perf.ClientSet, fmt.Sprintf("app=%s", name)) + if err != nil { + return err + } + } else { + perf.ClientAcross, err = GetNakedPods(perf.ClientSet, fmt.Sprintf("app=%s", name)) + if err != nil { + return err + } + } + perf.ClientNodeInfo, _ = GetNakedPodNodeInfo(perf.ClientSet, fmt.Sprintf("app=%s", name)) return nil } @@ -688,6 +702,7 @@ func GetNakedPodNodeInfo(c *kubernetes.Clientset, label string) (metrics.NodeInf var info metrics.NodeInfo listOpt := metav1.ListOptions{ LabelSelector: label, + FieldSelector: "status.phase=Running", } pods, err := c.CoreV1().Pods(namespace).List(context.TODO(), listOpt) if err != nil { diff --git a/pkg/k8s/kubevirt.go b/pkg/k8s/kubevirt.go index 163c3457..ee2d72a7 100644 --- a/pkg/k8s/kubevirt.go +++ b/pkg/k8s/kubevirt.go @@ -153,12 +153,10 @@ func exposeService(client *kubernetes.Clientset, dynamicClient *dynamic.DynamicC } func CreateVMClient(kclient *kubevirtv1.KubevirtV1Client, client *kubernetes.Clientset, - dyn *dynamic.DynamicClient, role string, name string, - podAff *corev1.PodAntiAffinity, - nodeAff *corev1.NodeAffinity) (string, error) { + dyn *dynamic.DynamicClient, name string, podAff *corev1.PodAntiAffinity, nodeAff *corev1.NodeAffinity) (string, error) { label := map[string]string{ "app": name, - "role": role, + "role": name, } dirname, err := os.UserHomeDir() if err != nil { @@ -192,7 +190,7 @@ runcmd: - cd - curl -o /usr/bin/super-netperf https://raw.githubusercontent.com/cloud-bulldozer/k8s-netperf/main/containers/super-netperf - chmod 0777 /usr/bin/super-netperf -`, string(ssh)) +`, ssh) _, err = CreateVMI(kclient, name, label, b64.StdEncoding.EncodeToString([]byte(data)), *podAff, *nodeAff) if err != nil { return "", err @@ -208,8 +206,7 @@ runcmd: return host, nil } -func CreateVMServer(client *kubevirtv1.KubevirtV1Client, name string, role string, - podAff corev1.PodAntiAffinity, +func CreateVMServer(client *kubevirtv1.KubevirtV1Client, name string, role string, podAff corev1.PodAntiAffinity, nodeAff corev1.NodeAffinity) (*v1.VirtualMachineInstance, error) { label := map[string]string{ "app": name, @@ -252,8 +249,7 @@ runcmd: return CreateVMI(client, name, label, b64.StdEncoding.EncodeToString([]byte(data)), podAff, nodeAff) } -func CreateVMI(client *kubevirtv1.KubevirtV1Client, name string, label map[string]string, b64data string, - podAff corev1.PodAntiAffinity, +func CreateVMI(client *kubevirtv1.KubevirtV1Client, name string, label map[string]string, b64data string, podAff corev1.PodAntiAffinity, nodeAff corev1.NodeAffinity) (*v1.VirtualMachineInstance, error) { delSeconds := int64(0) mutliQ := true From 5356eb6a2c876e6ffed083f6982720e93ebf399b Mon Sep 17 00:00:00 2001 From: Joe Talerico aka rook Date: Mon, 9 Sep 2024 13:51:12 -0400 Subject: [PATCH 14/19] Addressing Vishnu's feedback Signed-off-by: Joe Talerico aka rook --- pkg/drivers/iperf.go | 16 ++++++---------- pkg/drivers/netperf.go | 16 ++++++---------- pkg/drivers/uperf.go | 27 ++++++++++----------------- 3 files changed, 22 insertions(+), 37 deletions(-) diff --git a/pkg/drivers/iperf.go b/pkg/drivers/iperf.go index f0a19983..0ae7fe52 100644 --- a/pkg/drivers/iperf.go +++ b/pkg/drivers/iperf.go @@ -128,13 +128,11 @@ func (i *iperf3) Run(c *kubernetes.Clientset, for i := 0; i <= retry; i++ { log.Debug("⏰ Waiting for iperf3 to be present on VM") _, err = sshclient.Run("until iperf3 -h; do sleep 30; done") - if err != nil { - time.Sleep(10 * time.Second) - continue - } else { + if err == nil { present = true break } + time.Sleep(10 * time.Second) } if !present { sshclient.Close() @@ -144,15 +142,13 @@ func (i *iperf3) Run(c *kubernetes.Clientset, ran := false for i := 0; i <= retry; i++ { stdout, err = sshclient.Run(strings.Join(cmd[:], " ")) - if err != nil { - log.Debugf("Failed running command %s", err) - log.Debugf("⏰ Retrying iperf3 command -- cloud-init still finishing up") - time.Sleep(60 * time.Second) - continue - } else { + if err == nil { ran = true break } + log.Debugf("Failed running command %s", err) + log.Debugf("⏰ Retrying iperf3 command -- cloud-init still finishing up") + time.Sleep(60 * time.Second) } sshclient.Close() if !ran { diff --git a/pkg/drivers/netperf.go b/pkg/drivers/netperf.go index 453b37ad..63dba7d8 100644 --- a/pkg/drivers/netperf.go +++ b/pkg/drivers/netperf.go @@ -107,13 +107,11 @@ func (n *netperf) Run(c *kubernetes.Clientset, rc rest.Config, nc config.Config, for i := 0; i <= retry; i++ { log.Debug("⏰ Waiting for netperf to be present on VM") _, err = sshclient.Run("until which netperf; do sleep 30; done") - if err != nil { - time.Sleep(10 * time.Second) - continue - } else { + if err == nil { present = true break } + time.Sleep(10 * time.Second) } if !present { sshclient.Close() @@ -123,15 +121,13 @@ func (n *netperf) Run(c *kubernetes.Clientset, rc rest.Config, nc config.Config, ran := false for i := 0; i <= retry; i++ { _, err = sshclient.Run(fmt.Sprintf("netperf -H %s -l 1 -- %s", serverIP, strconv.Itoa(k8s.NetperfServerDataPort))) - if err != nil { - log.Debugf("Failed running command %s", err) - log.Debugf("⏰ Retrying netperf command -- cloud-init still finishing up") - time.Sleep(60 * time.Second) - continue - } else { + if err == nil { ran = true break } + log.Debugf("Failed running command %s", err) + log.Debugf("⏰ Retrying netperf command -- cloud-init still finishing up") + time.Sleep(60 * time.Second) } stdout, err = sshclient.Run(strings.Join(cmd[:], " ")) if err != nil { diff --git a/pkg/drivers/uperf.go b/pkg/drivers/uperf.go index 264d579e..14c0fd40 100644 --- a/pkg/drivers/uperf.go +++ b/pkg/drivers/uperf.go @@ -215,13 +215,11 @@ func (u *uperf) Run(c *kubernetes.Clientset, rc rest.Config, nc config.Config, c for i := 0; i <= retry; i++ { log.Debug("⏰ Waiting for uperf to be present on VM") _, err = sshclient.Run("until uperf -h; do sleep 30; done") - if err != nil { - time.Sleep(10 * time.Second) - continue - } else { + if err == nil { present = true break } + time.Sleep(10 * time.Second) } if !present { sshclient.Close() @@ -231,15 +229,13 @@ func (u *uperf) Run(c *kubernetes.Clientset, rc rest.Config, nc config.Config, c ran := false for i := 0; i <= retry; i++ { stdout, err = sshclient.Run(strings.Join(cmd[:], " ")) - if err != nil { - log.Debugf("Failed running command %s", err) - log.Debugf("⏰ Retrying uperf command -- cloud-init still finishing up") - time.Sleep(60 * time.Second) - continue - } else { + if err == nil { ran = true break } + log.Debugf("Failed running command %s", err) + log.Debugf("⏰ Retrying uperf command -- cloud-init still finishing up") + time.Sleep(60 * time.Second) } sshclient.Close() if !ran { @@ -252,7 +248,7 @@ func (u *uperf) Run(c *kubernetes.Clientset, rc rest.Config, nc config.Config, c // ParseResults accepts the stdout from the execution of the benchmark. // It will return a Sample struct or error -func (u *uperf) ParseResults(stdout *bytes.Buffer, nc config.Config) (sample.Sample, error) { +func (u *uperf) ParseResults(stdout *bytes.Buffer, _ config.Config) (sample.Sample, error) { sample := sample.Sample{} sample.Driver = u.driverName sample.Metric = "Mb/s" @@ -285,13 +281,10 @@ func (u *uperf) ParseResults(stdout *bytes.Buffer, nc config.Config) (sample.Sam } averageByte, _ := stats.Mean(byteSummary) - if strings.Contains(nc.Profile, "STREAM") { - sample.Throughput = float64(averageByte*8) / 1000000 - } else { - sample.Throughput, _ = stats.Mean(opSummary) - } + averageOps, _ := stats.Mean(opSummary) + sample.Throughput = float64(averageByte*8) / 1000000 sample.Latency99ptile, _ = stats.Percentile(latSummary, 99) - log.Debugf("Storing uperf sample Average bytes: %f , P99 Latency %f, Throughput: %f ", averageByte, sample.Latency99ptile, sample.Throughput) + log.Debugf("Storing uperf sample throughput: %f Mbps, P99 Latency %f, Average ops: %f ", sample.Throughput, sample.Latency99ptile, averageOps) return sample, nil From 4c006e8a9ddf91e6686ee0580349ad31f275ea3f Mon Sep 17 00:00:00 2001 From: Joe Talerico aka rook Date: Mon, 9 Sep 2024 15:42:24 -0400 Subject: [PATCH 15/19] Update README.md Signed-off-by: Joe Talerico aka rook --- README.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f13bab65..fa6fe2d0 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ $ cd k8s-netperf $ make docker-build ``` -## Running +## Running with Pods Ensure your `kubeconfig` is properly set to the cluster you would like to run `k8s-netperf` against. also be sure to create a `netperf` namespace. (Not over-writable yet) @@ -95,6 +95,17 @@ Flags: > *Note: With OpenShift, we attempt to discover the OpenShift route. If that route is not reachable, it might be required to `port-forward` the service and pass that via the `--prom` option.* +## Running with VMs +Running k8s-netperf against Virtual Machines (OpenShift CNV) requires + +- OpenShift CNV must be deployed and users should be able to define VMIs +- SSH keys to be present in the home directory `(~/.ssh/id_rsa.pub)` +- OpenShift Routes - k8s-netperf uses this to reach the VMs (k8s-netperf will create the route for the user, but we need Routes) + +If the two above are in place, users can orhestrate k8s-netperf to launch VMs by running + +`k8s-netperf --vm` + ### Config file #### Config File v2 The v2 config file will be executed in the order the tests are presented in the config file. From 2de69c173a4fcaa0283aba288eb7c30a7a4b362c Mon Sep 17 00:00:00 2001 From: Joe Talerico aka rook Date: Tue, 10 Sep 2024 08:00:24 -0400 Subject: [PATCH 16/19] Adding virt to metadata Signed-off-by: Joe Talerico aka rook --- cmd/k8s-netperf/k8s-netperf.go | 1 + pkg/archive/archive.go | 2 ++ pkg/results/result.go | 1 + 3 files changed, 4 insertions(+) diff --git a/cmd/k8s-netperf/k8s-netperf.go b/cmd/k8s-netperf/k8s-netperf.go index ad097627..cd53be91 100644 --- a/cmd/k8s-netperf/k8s-netperf.go +++ b/cmd/k8s-netperf/k8s-netperf.go @@ -219,6 +219,7 @@ var rootCmd = &cobra.Command{ } } } else { + sr.Virt = true log.Info("Connecting via ssh to the VMI") client, err := k8s.SSHConnect(&s) if err != nil { diff --git a/pkg/archive/archive.go b/pkg/archive/archive.go index 8255db62..385a67c7 100644 --- a/pkg/archive/archive.go +++ b/pkg/archive/archive.go @@ -28,6 +28,7 @@ type Doc struct { Duration int `json:"duration"` Service bool `json:"service"` Local bool `json:"local"` + Virt bool `json:"virt"` AcrossAZ bool `json:"acrossAZ"` Samples int `json:"samples"` Messagesize int `json:"messageSize"` @@ -97,6 +98,7 @@ func BuildDocs(sr result.ScenarioResults, uuid string) ([]interface{}, error) { Parallelism: r.Parallelism, Profile: r.Profile, Duration: r.Duration, + Virt: sr.Virt, Samples: r.Samples, Service: r.Service, Messagesize: r.MessageSize, diff --git a/pkg/results/result.go b/pkg/results/result.go index 22f5d72f..a3d64766 100644 --- a/pkg/results/result.go +++ b/pkg/results/result.go @@ -51,6 +51,7 @@ type Data struct { // ScenarioResults each scenario could have multiple results type ScenarioResults struct { Results []Data + Virt bool Version string GitCommit string Metadata From 27066818046960d16774f244089afff0e1074ab7 Mon Sep 17 00:00:00 2001 From: Joe Talerico aka rook Date: Tue, 10 Sep 2024 13:46:41 -0400 Subject: [PATCH 17/19] Allow the user to override the index needed for BM ES Signed-off-by: Joe Talerico aka rook --- cmd/k8s-netperf/k8s-netperf.go | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/cmd/k8s-netperf/k8s-netperf.go b/cmd/k8s-netperf/k8s-netperf.go index cd53be91..e093ed5c 100644 --- a/cmd/k8s-netperf/k8s-netperf.go +++ b/cmd/k8s-netperf/k8s-netperf.go @@ -51,6 +51,7 @@ var ( json bool version bool csvArchive bool + searchIndex string ) var rootCmd = &cobra.Command{ @@ -284,13 +285,22 @@ var rootCmd = &cobra.Command{ } if len(searchURL) > 1 { + var esClient *indexers.Indexer jdocs, err := archive.BuildDocs(sr, uid) if err != nil { log.Fatal(err) } - esClient, err := archive.Connect(searchURL, index, true) - if err != nil { - log.Fatal(err) + if len(searchIndex) > 1 { + esClient, err = archive.Connect(searchURL, searchIndex, true) + if err != nil { + log.Fatal(err) + } + } else { + esClient, err = archive.Connect(searchURL, index, true) + if err != nil { + log.Fatal(err) + } + } log.Infof("Indexing [%d] documents in %s with UUID %s", len(jdocs), index, uid) resp, err := (*esClient).Index(jdocs, indexers.IndexingOpts{}) @@ -476,6 +486,7 @@ func main() { rootCmd.Flags().StringVar(&promURL, "prom", "", "Prometheus URL") rootCmd.Flags().StringVar(&id, "uuid", "", "User provided UUID") rootCmd.Flags().StringVar(&searchURL, "search", "", "OpenSearch URL, if you have auth, pass in the format of https://user:pass@url:port") + rootCmd.Flags().StringVar(&searchIndex, "index", "", "OpenSearch Index to save the results to, defaults to k8s-netperf") rootCmd.Flags().BoolVar(&showMetrics, "metrics", false, "Show all system metrics retrieved from prom") rootCmd.Flags().Float64Var(&tcpt, "tcp-tolerance", 10, "Allowed %diff from hostNetwork to podNetwork, anything above tolerance will result in k8s-netperf exiting 1.") rootCmd.Flags().BoolVar(&version, "version", false, "k8s-netperf version") From c0701a61c1d6fa70a698bf77153e3818b755f0d3 Mon Sep 17 00:00:00 2001 From: Joe Talerico aka rook Date: Tue, 10 Sep 2024 16:44:06 -0400 Subject: [PATCH 18/19] Reducing metrics sent to ES We don't select based on any of these node labels, no need to send them, and they were causing issues (since we had > 1000 fields thanks to CNV). Signed-off-by: Joe Talerico aka rook --- pkg/archive/archive.go | 48 ++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/pkg/archive/archive.go b/pkg/archive/archive.go index 385a67c7..c3719b29 100644 --- a/pkg/archive/archive.go +++ b/pkg/archive/archive.go @@ -89,31 +89,29 @@ func BuildDocs(sr result.ScenarioResults, uuid string) ([]interface{}, error) { } c := []float64{lo, hi} d := Doc{ - UUID: uuid, - Timestamp: time, - ToolVersion: sr.Version, - ToolGitCommit: sr.GitCommit, - Driver: r.Driver, - HostNetwork: r.HostNetwork, - Parallelism: r.Parallelism, - Profile: r.Profile, - Duration: r.Duration, - Virt: sr.Virt, - Samples: r.Samples, - Service: r.Service, - Messagesize: r.MessageSize, - Burst: r.Burst, - TputMetric: r.Metric, - LtcyMetric: ltcyMetric, - ServerNodeCPU: r.ServerMetrics, - ClientNodeCPU: r.ClientMetrics, - ServerPodCPU: r.ServerPodCPU.Results, - ClientPodCPU: r.ClientPodCPU.Results, - Metadata: sr.Metadata, - ServerNodeLabels: r.ServerNodeLabels, - ClientNodeLabels: r.ClientNodeLabels, - AcrossAZ: r.AcrossAZ, - Confidence: c, + UUID: uuid, + Timestamp: time, + ToolVersion: sr.Version, + ToolGitCommit: sr.GitCommit, + Driver: r.Driver, + HostNetwork: r.HostNetwork, + Parallelism: r.Parallelism, + Profile: r.Profile, + Duration: r.Duration, + Virt: sr.Virt, + Samples: r.Samples, + Service: r.Service, + Messagesize: r.MessageSize, + Burst: r.Burst, + TputMetric: r.Metric, + LtcyMetric: ltcyMetric, + ServerNodeCPU: r.ServerMetrics, + ClientNodeCPU: r.ClientMetrics, + ServerPodCPU: r.ServerPodCPU.Results, + ClientPodCPU: r.ClientPodCPU.Results, + Metadata: sr.Metadata, + AcrossAZ: r.AcrossAZ, + Confidence: c, } UDPLossPercent, e := result.Average(r.LossSummary) if e != nil { From a4a6ae12169984137dc85359832b8bc09f133ba9 Mon Sep 17 00:00:00 2001 From: Joe Talerico aka rook Date: Wed, 11 Sep 2024 14:23:37 -0400 Subject: [PATCH 19/19] Code comments Signed-off-by: Joe Talerico aka rook --- pkg/k8s/kubernetes.go | 2 ++ pkg/k8s/kubevirt.go | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/pkg/k8s/kubernetes.go b/pkg/k8s/kubernetes.go index 41d09bdc..8a629613 100644 --- a/pkg/k8s/kubernetes.go +++ b/pkg/k8s/kubernetes.go @@ -72,6 +72,7 @@ const hostNetServerRole = "host-server" const hostNetClientRole = "host-client" const k8sNetperfImage = "quay.io/cloud-bulldozer/k8s-netperf:latest" +// BuildInfra will create the infra for the SUT func BuildInfra(client *kubernetes.Clientset) error { _, err := client.CoreV1().Namespaces().Get(context.TODO(), namespace, metav1.GetOptions{}) if err == nil { @@ -748,6 +749,7 @@ func GetPods(c *kubernetes.Clientset, dp DeploymentParams) (corev1.PodList, erro return npl, nil } +// GetNakedPods when we deploy pods without a higher-level controller like deployment func GetNakedPods(c *kubernetes.Clientset, label string) (corev1.PodList, error) { npl := corev1.PodList{} listOpt := metav1.ListOptions{ diff --git a/pkg/k8s/kubevirt.go b/pkg/k8s/kubevirt.go index ee2d72a7..6834ee4c 100644 --- a/pkg/k8s/kubevirt.go +++ b/pkg/k8s/kubevirt.go @@ -30,6 +30,7 @@ var ( retry = 30 ) +// connect will attempt to connect via ssh to the guest. The VM can take a while for sshkeys to be injected func connect(config *goph.Config) (*goph.Client, error) { for i := 0; i < retry; i++ { client, err := goph.NewConn(config) @@ -45,6 +46,7 @@ func connect(config *goph.Config) (*goph.Client, error) { return nil, fmt.Errorf("Unable to connect via ssh after %d attempts", retry) } +// SSHConnect sets up the ssh config, then attempts to connect to the VM. func SSHConnect(conf *config.PerfScenarios) (*goph.Client, error) { dir, err := os.UserHomeDir() if err != nil { @@ -79,6 +81,7 @@ func SSHConnect(conf *config.PerfScenarios) (*goph.Client, error) { return client, nil } +// createCommService creates a SSH nodeport service using port 32022 -> 22 func createCommService(client *kubernetes.Clientset, label map[string]string, name string) error { log.Infof("🚀 Creating service for %s in namespace %s", name, namespace) sc := client.CoreV1().Services(namespace) @@ -105,6 +108,7 @@ func createCommService(client *kubernetes.Clientset, label map[string]string, na return err } +// exposeService will create a route for the ssh nodeport service. func exposeService(client *kubernetes.Clientset, dynamicClient *dynamic.DynamicClient, svcName string) (string, error) { gvr := schema.GroupVersionResource{ Group: "route.openshift.io", @@ -152,6 +156,7 @@ func exposeService(client *kubernetes.Clientset, dynamicClient *dynamic.DynamicC return host, nil } +// CreateVMClient takes in the affinity rules and deploys the VMI func CreateVMClient(kclient *kubevirtv1.KubevirtV1Client, client *kubernetes.Clientset, dyn *dynamic.DynamicClient, name string, podAff *corev1.PodAntiAffinity, nodeAff *corev1.NodeAffinity) (string, error) { label := map[string]string{ @@ -206,6 +211,7 @@ runcmd: return host, nil } +// CreateVMServer will take the pod and node affinity and deploy the VMI func CreateVMServer(client *kubevirtv1.KubevirtV1Client, name string, role string, podAff corev1.PodAntiAffinity, nodeAff corev1.NodeAffinity) (*v1.VirtualMachineInstance, error) { label := map[string]string{ @@ -249,6 +255,7 @@ runcmd: return CreateVMI(client, name, label, b64.StdEncoding.EncodeToString([]byte(data)), podAff, nodeAff) } +// CreateVMI creates the desired Virtual Machine instance with the cloud-init config with affinity. func CreateVMI(client *kubevirtv1.KubevirtV1Client, name string, label map[string]string, b64data string, podAff corev1.PodAntiAffinity, nodeAff corev1.NodeAffinity) (*v1.VirtualMachineInstance, error) { delSeconds := int64(0) @@ -321,6 +328,7 @@ func CreateVMI(client *kubevirtv1.KubevirtV1Client, name string, label map[strin return vmi, nil } +// WaitForVMI will wait until the resource is in Running state. func WaitForVMI(client *kubevirtv1.KubevirtV1Client, name string) error { log.Infof("⏰ Wating for VMI (%s) to be in state running", name) vmw, err := client.VirtualMachineInstances(namespace).Watch(context.TODO(), metav1.ListOptions{})