Skip to content
This repository has been archived by the owner on Apr 25, 2023. It is now read-only.

Commit

Permalink
test: add validation and tests for the proxy-url
Browse files Browse the repository at this point in the history
Signed-off-by: Hector Fernandez <[email protected]>
  • Loading branch information
hectorj2f committed Mar 16, 2021
1 parent 42028cc commit ecf203c
Show file tree
Hide file tree
Showing 7 changed files with 216 additions and 6 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ require (
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.6.1
go.uber.org/zap v1.16.0 // indirect
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b
k8s.io/api v0.20.2
k8s.io/apiextensions-apiserver v0.20.2
k8s.io/apimachinery v0.20.2
Expand Down
77 changes: 77 additions & 0 deletions pkg/apis/core/v1beta1/kubefedcluster_types_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
Copyright 2021 The Kubernetes Authors.
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.
*/

package v1beta1

import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"sigs.k8s.io/controller-runtime/pkg/client"

"golang.org/x/net/context"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
)

var _ = Describe("KubefedCluster", func() {
var (
key types.NamespacedName
created, fetched *KubeFedCluster
)

BeforeEach(func() {

})

AfterEach(func() {

})

Context("Create API", func() {

It("should create a kubefed cluster successfully", func() {

created = &KubeFedCluster{
ObjectMeta: metav1.ObjectMeta{
Name: "foo",
Namespace: metav1.NamespaceDefault,
},
Spec: KubeFedClusterSpec{
APIEndpoint: "https://my.example.com:80/path/to/endpoint",
ProxyURL: "socks5://example.com",
SecretRef: LocalSecretReference{
Name: "foo",
},
},
}

key, _ = client.ObjectKeyFromObject(created)

By("creating an API obj")
Expect(k8sClient.Create(context.TODO(), created)).To(Succeed())

fetched = &KubeFedCluster{}
Expect(k8sClient.Get(context.TODO(), key, fetched)).To(Succeed())
Expect(fetched).To(Equal(created))

By("deleting the created object")
Expect(k8sClient.Delete(context.TODO(), created)).To(Succeed())
Expect(k8sClient.Get(context.TODO(), key, created)).ToNot(Succeed())
})

})

})
65 changes: 65 additions & 0 deletions pkg/apis/core/v1beta1/suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package v1beta1

import (
"path/filepath"
"testing"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"

"k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/rest"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/envtest"
"sigs.k8s.io/controller-runtime/pkg/envtest/printer"
logf "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
)

var cfg *rest.Config
var k8sClient client.Client
var testEnv *envtest.Environment

func TestAPIs(t *testing.T) {
RegisterFailHandler(Fail)

RunSpecsWithDefaultAndCustomReporters(t,
"v1beta1 Suite",
[]Reporter{printer.NewlineReporter{}})
}

var _ = BeforeSuite(func(done Done) {
logf.SetLogger(zap.New(func(o *zap.Options) {
o.Development = true
o.DestWritter = GinkgoWriter
}))

By("bootstrapping test environment")
testEnv = &envtest.Environment{
CRDInstallOptions: envtest.CRDInstallOptions{
ErrorIfPathMissing: true,
Paths: []string{
filepath.Join("..", "..", "..", "..", "charts", "kubefed", "charts", "controllermanager", "crds"),
},
},
}

err := SchemeBuilder.AddToScheme(scheme.Scheme)
Expect(err).NotTo(HaveOccurred())

cfg, err = testEnv.Start()
Expect(err).ToNot(HaveOccurred())
Expect(cfg).ToNot(BeNil())

k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme})
Expect(err).ToNot(HaveOccurred())
Expect(k8sClient).ToNot(BeNil())

close(done)
}, 60)

var _ = AfterSuite(func() {
By("tearing down the test environment")
err := testEnv.Stop()
Expect(err).ToNot(HaveOccurred())
})
19 changes: 19 additions & 0 deletions pkg/apis/core/v1beta1/validation/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package validation

import (
"fmt"
"net/url"
"strconv"
"strings"
"time"
Expand Down Expand Up @@ -163,6 +164,9 @@ func validateKubeFedClusterSpec(spec *v1beta1.KubeFedClusterSpec, path *field.Pa
allErrs := validateAPIEndpoint(spec.APIEndpoint, path.Child("apiEndpoint"))
allErrs = append(allErrs, validateLocalSecretReference(&spec.SecretRef, path.Child("secretRef"))...)
allErrs = append(allErrs, validateDisabledTLSValidations(spec.DisabledTLSValidations, path.Child("disabledTLSValidations"))...)
if spec.ProxyURL != "" {
allErrs = append(allErrs, validateProxyURL(spec.ProxyURL, path.Child("proxyURL"))...)
}
return allErrs
}

Expand All @@ -175,6 +179,21 @@ func validateKubeFedClusterStatus(status *v1beta1.KubeFedClusterStatus, path *fi
return allErrs
}

func validateProxyURL(proxyURL string, path *field.Path) field.ErrorList {
var allErrs field.ErrorList

u, err := url.Parse(proxyURL)
if err != nil {
allErrs = append(allErrs, field.Invalid(path, proxyURL, "error parsing the proxy URL"))
}
switch u.Scheme {
case "http", "https", "socks5":
default:
allErrs = append(allErrs, field.Invalid(path, proxyURL, "proxy URL scheme must be one of: [http, https, socks5]"))
}
return allErrs
}

func validateAPIEndpoint(endpoint string, path *field.Path) field.ErrorList {
if endpoint == "" {
return field.ErrorList{field.Required(path, "")}
Expand Down
50 changes: 50 additions & 0 deletions pkg/apis/core/v1beta1/validation/validation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,56 @@ func TestValidateAPIEndpoint(t *testing.T) {
}
}

func TestProxyURL(t *testing.T) {
tests := []struct {
proxyURL string
expectedErrMsg string
}{
{
proxyURL: "socks5://example.com",
},
{
proxyURL: "https://example.com",
},
{
proxyURL: "http://example.com",
},
{
proxyURL: "socks6://example.com",
expectedErrMsg: "proxyURL: Invalid value: \"socks6://example.com\": proxy URL scheme must be one of: [http, https, socks5]",
},
{
proxyURL: "example.com",
expectedErrMsg: "proxyURL: Invalid value: \"example.com\": proxy URL scheme must be one of: [http, https, socks5]",
},
{
proxyURL: "[email protected]",
expectedErrMsg: "proxyURL: Invalid value: \"[email protected]\": proxy URL scheme must be one of: [http, https, socks5]",
},
}

for _, test := range tests {
errs := validateProxyURL(test.proxyURL, field.NewPath("proxyURL"))
if len(errs) == 0 && test.expectedErrMsg == "" {
continue
}
if len(errs) == 0 && test.expectedErrMsg != "" {
t.Errorf("[%s] expected failure", test.expectedErrMsg)
} else {
matchedErr := false
for _, err := range errs {
if strings.Contains(err.Error(), test.expectedErrMsg) {
matchedErr = true
break
}
}
if !matchedErr {
t.Errorf("unexpected error: %v, expected: %q", errs, test.expectedErrMsg)
}
}
}
}

func TestValidateLocalSecretReference(t *testing.T) {
testCases := []struct {
secretName string
Expand Down
3 changes: 1 addition & 2 deletions pkg/controller/util/cluster_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ const (
KubeAPIQPS = 20.0
KubeAPIBurst = 30
TokenKey = "token"
ProxyURLKey = "proxy-url"

KubeFedConfigName = "kubefed"
)
Expand Down Expand Up @@ -88,7 +87,7 @@ func BuildClusterConfig(fedCluster *fedv1b1.KubeFedCluster, client generic.Clien
if fedCluster.Spec.ProxyURL != "" {
proxyURL, err := url.Parse(fedCluster.Spec.ProxyURL)
if err != nil {
return nil, errors.Errorf("Failed to parse provided proxy-url %s: %v", fedCluster.Spec.ProxyURL, err)
return nil, errors.Errorf("Failed to parse provided proxy URL %s: %v", fedCluster.Spec.ProxyURL, err)
}
clusterConfig.Proxy = http.ProxyURL(proxyURL)
}
Expand Down
7 changes: 3 additions & 4 deletions pkg/kubefedctl/join.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package kubefedctl
import (
"context"
goerrors "errors"
"fmt"
"io"
"net/http"
"reflect"
Expand Down Expand Up @@ -282,12 +281,12 @@ func joinClusterForNamespace(hostConfig, clusterConfig *rest.Config, kubefedName
if clusterConfig.Proxy != nil {
req, err := http.NewRequest("", clusterConfig.Host, nil)
if err != nil {
return nil, fmt.Errorf("failed to create proxy URL request for kubefed cluster: %w", err)
return nil, errors.Errorf("failed to create proxy URL request for kubefed cluster: %v", err)
}
url, err := clusterConfig.Proxy(req)
if err != nil {
klog.V(2).Infof("Error getting Proxy URL for host %s: %w", clusterConfig.Host, err)
return nil, fmt.Errorf("failed to create proxy URL request for kubefed cluster: %w", err)
klog.V(2).Infof("Error getting proxy URL for host %s: %w", clusterConfig.Host, err)
return nil, errors.Errorf("failed to create proxy URL request for kubefed cluster: %v", err)
}
if url != nil {
proxyURL = url.String()
Expand Down

0 comments on commit ecf203c

Please sign in to comment.