Skip to content

Commit

Permalink
UT Coverage Improvement (#7)
Browse files Browse the repository at this point in the history
* Additional Units tests
  • Loading branch information
Inbaraj-S authored Jul 3, 2023
1 parent ca733ae commit af092f4
Show file tree
Hide file tree
Showing 31 changed files with 3,279 additions and 555 deletions.
1 change: 0 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ push:
docker push ${IMAGE_PATH}

build-push: image push
docker push ${IMAGE_PATH}

.PHONY: coverage
coverage: test
Expand Down
43 changes: 15 additions & 28 deletions pkg/auth/auth_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,17 @@ import (
"k8s.io/api/core/v1"
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/klog/v2"

"github.com/oracle/oci-native-ingress-controller/pkg/types"
)

const httpClientTimeout = 20 * time.Second

func GetConfigurationProvider(ctx context.Context, opts types.IngressOpts) (common.ConfigurationProvider, error) {
auth, err := RetrieveAuthConfig(ctx, opts, opts.LeaseLockNamespace)
func GetConfigurationProvider(ctx context.Context, opts types.IngressOpts, client kubernetes.Interface) (common.ConfigurationProvider, error) {
auth, err := RetrieveAuthConfig(ctx, opts, opts.LeaseLockNamespace, client)
if err != nil {
klog.Fatalf("Unable to handle authentication parameters", err)
klog.Error("Unable to handle authentication parameters", err)
return nil, err
}
return getConfProviderFromAuth(auth)
Expand Down Expand Up @@ -71,7 +70,7 @@ func setHTTPClientTimeout(
}
}

func RetrieveAuthConfig(ctx context.Context, opts types.IngressOpts, namespace string) (*types.Auth, error) {
func RetrieveAuthConfig(ctx context.Context, opts types.IngressOpts, namespace string, client kubernetes.Interface) (*types.Auth, error) {
authType := opts.AuthType
principalType, err := types.MapToPrincipalType(authType)
if err != nil {
Expand All @@ -86,27 +85,27 @@ func RetrieveAuthConfig(ctx context.Context, opts types.IngressOpts, namespace s
authConfigSecretName := opts.AuthSecretName

// read it from k8s api
secret, err := readK8sSecret(ctx, namespace, authConfigSecretName)
secret, err := readK8sSecret(ctx, namespace, authConfigSecretName, client)
if err != nil {
klog.Fatalf("Error while reading secret from k8s api", err)
klog.Error("Error while reading secret from k8s api", err)
return nil, fmt.Errorf("error retrieving secret: %v", authConfigSecretName)
}

klog.Infof("secret is retrieved from kubernetes api: %s", authConfigSecretName)

if len(secret.Data) == 0 || len(secret.Data["config"]) == 0 {
klog.Fatalf("Empty Configuration is found in the secret %s", authConfigSecretName)
klog.Error("Empty Configuration is found in the secret %s", authConfigSecretName)
return nil, fmt.Errorf("auth config data is empty: %v", authConfigSecretName)
}
authCfg, err := ParseAuthConfig(secret, authConfigSecretName)
if err != nil {
klog.Fatalf("Missing auth config data: %s", authConfigSecretName)
klog.Error("Missing auth config data: %s", authConfigSecretName)
return nil, fmt.Errorf("missing auth config data: %v", err)
}

err = authCfg.Validate()
if err != nil {
klog.Fatalf("Missing auth config data %s", authConfigSecretName)
klog.Error("Missing auth config data %s", authConfigSecretName)
return nil, fmt.Errorf("missing auth config data: %v", err)
}
auth.Config = *authCfg
Expand All @@ -117,40 +116,28 @@ func RetrieveAuthConfig(ctx context.Context, opts types.IngressOpts, namespace s
func ParseAuthConfig(secret *v1.Secret, authConfigSecretName string) (*types.AuthConfig, error) {
authYaml := &types.AuthConfigYaml{}
err := yaml.Unmarshal(secret.Data["config"], &authYaml)
if err != nil {
klog.Fatalf("Invalid auth config data %s", authConfigSecretName)
if err != nil || authYaml.Auth == nil {
klog.Errorf("Invalid auth config data %s", authConfigSecretName)
return nil, fmt.Errorf("invalid auth config data: %v", authConfigSecretName)
}

if len(secret.Data["private-key"]) > 0 {
authYaml.Auth["privateKey"] = string(secret.Data["private-key"])
} else {
klog.Fatalf("Invalid user auth private key %s", authConfigSecretName)
klog.Errorf("Invalid user auth private key %s", authConfigSecretName)
return nil, fmt.Errorf("invalid user auth config data: %v", authConfigSecretName)
}

authCfgYaml, _ := yaml.Marshal(authYaml.Auth)
authCfg := &types.AuthConfig{}
err = yaml.Unmarshal(authCfgYaml, &authCfg)
if err != nil {
klog.Fatalf("Invalid auth config data %s", authConfigSecretName)
klog.Errorf("Invalid auth config data %s", authConfigSecretName)
return nil, fmt.Errorf("invalid auth config data: %v", authConfigSecretName)
}
return authCfg, nil
}

func readK8sSecret(ctx context.Context, namespace string,
secretName string) (*v1.Secret, error) {
clusterCfg, err := rest.InClusterConfig()
if err != nil {
return &v1.Secret{}, fmt.Errorf("can not get cluster config. error: %v", err)
}

clientSet, err := kubernetes.NewForConfig(clusterCfg)
if err != nil {
return &v1.Secret{}, fmt.Errorf("can not initialize kubernetes client. error: %v", err)
}

k8client := clientSet.CoreV1()
return k8client.Secrets(namespace).Get(ctx, secretName, metaV1.GetOptions{})
func readK8sSecret(ctx context.Context, namespace string, secretName string, client kubernetes.Interface) (*v1.Secret, error) {
return client.CoreV1().Secrets(namespace).Get(ctx, secretName, metaV1.GetOptions{})
}
116 changes: 98 additions & 18 deletions pkg/auth/auth_service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,92 @@ package auth

import (
"context"
"encoding/base64"
"fmt"
"net/http"
"testing"

. "github.com/onsi/gomega"
"github.com/oracle/oci-native-ingress-controller/pkg/types"
"github.com/oracle/oci-native-ingress-controller/pkg/util"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
fakeclientset "k8s.io/client-go/kubernetes/fake"
)

const (
PrivateKey = "SSLPrivateData = `-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAyxPEO9rowYQ6/sjpD4VxnGdChokq4b8LyOcnIFRMueihl+8S\napqbe96A3etQaMBANx2FcuFt9FcPSJaJU93i9hkw/FPa5d2+Kr7wgE3pwOPXPqOI\nxuaeQfUIZ4QcGNSs1utsSbj/i3RvJDgrUOI+RypT4erpQX2cQZ5tplaDd2SxBYWW\nyZUkVIRPXKyJm4Yft1CsKDtbEzzIdh69DlfyfWRDYWxfD9D/RflmDafbunXo1OC2\nUJ3MHi+tD2NxgCFVvOWiiE+BMD28e3mGVg6WvoFtcutahnvrFocHDWnoMK269AbI\nrZ1WuUKBxOlbWLz9XbbsxFYDskRqNk22GtrQ3QIDAQABAoIBACU1cfclnRAYElcs\nqMdXRAHMSbws1daXEqm08M5To9tMbI9SFqXBvktr8WC4BPusfhebKSBrfaIPcZVz\nP6ZGOZet9fPFyY3kmztp0Ncxb2sQVBf+Dsmi58xeATQ2WI+UKDcY27aGVwxOQS75\nu7YOPir77nKugB6nzUGYra6Um3H8hYNWTgWyiATb8Y0V4njCf8pAepGOptClyI1I\ni5fsEE6q52jbGeFRK2JTysG8ovABBdGYsS8XOUuZ+O/QktF/iFwFtMWdEur5tcOO\nRoPSrc/4H8pNpL7IhF0Iy/hpNoNsin7Gj4UBNi6dhrtcGz3zCGSKtldsootgSC2C\nKWd/rAECgYEA5sF6OZsLguVfCqmj3WiLM5I+YWC/HAmV9grb9puW35cQxfQegmdj\nInWk+rcotuFTBcTKjXDKT4C8vCZid2p0WnSWqLPWhPYg0p2awobZgjRy0HzvUgGJ\n/gWAEydzsUc8ojHrUBdJ2iyvjy+I8JWQcyQkBUGlPZj0IC5VUgODYD0CgYEA4Usg\nUCJqo35pLq0TmPSfUuMPzTV3StIft+r7S3g4HWpvrBQNKf6p96/Fjt2WaPhvAABB\nww8Pg2B97iSqR6Rg4Ba4BQQEfHtWCHQ2NuNOoNkRLTJqOxREk7+741Qy9EwgeDJ6\nrQqgrde1dLJPZDzQpbFoCLkIkQ6CL3jTkyDenSECgYEAmvZ1STgoy9eTMsrnY2mw\niYp9X9GjpYV+coOqYfrsn+yH9BfTYUli1qJgj4nuypmYsngMel2zTx6qIEQ6vez8\nhD5lapeSySmssyPp6Ra7/OeR7xbndI/aBn/VGYfV9shbHKUfXGK3Us/Nef+3G7Gl\nFt2/XtRNzobn8rCK1Y/MaxUCgYB6RFpKAxOanS0aLsX2+bNJuX7G4KBYE8cw+i7d\nG2Zg2HW4jr1CMDov+M2fpjRNzZ34AyutX4wMwZ42UuGytcv5cXr3BeIlaI4dUmxl\nx2DRvFwtCjJK08oP4TtnuTdaC8KHWOXo6V6gWfPZXDfn73VQpwIN0dWLW7NdbhZs\nv6bw4QKBgEXYPIf827EVz0XU+1wkjaLt+G40J9sAPk/a6qybF33BBbBhjDxMnest\nArGIjYo4IcYu5hzwnPy/B9WIFgz1iY31l01eP90zJ6q+xpCO5qSdSnjkfq1zrwzK\nBs7B72+hgS7VwRowRUbNanaZIZt0ZAiwQWN1+Dh7Bj+VbSxc/fna\n-----END RSA PRIVATE KEY-----`"
data = "IwojIE9DSSBOYXRpdmUgSW5ncmVzcyBDb250cm9sbGVyCiMKIyBDb3B5cmlnaHQgKGMpIDIwMjMgT3JhY2xlIEFtZXJpY2EsIEluYy4gYW5kIGl0cyBhZmZpbGlhdGVzLgojIExpY2Vuc2VkIHVuZGVyIHRoZSBVbml2ZXJzYWwgUGVybWlzc2l2ZSBMaWNlbnNlIHYgMS4wIGFzIHNob3duIGF0IGh0dHBzOi8vb3NzLm9yYWNsZS5jb20vbGljZW5zZXMvdXBsLwojCmF1dGg6CiAgcmVnaW9uOiB1cy1hc2hidXJuLTEKICBwYXNzcGhyYXNlOiBwYXNzCiAgdXNlcjogb2NpZDEudXNlci5vYzEuLmFhYWFhYWFhX2V4YW1wbGUKICBmaW5nZXJwcmludDogNjc6ZDk6NzQ6NGI6MjE6ZXhhbXBsZQogIHRlbmFuY3k6IG9jaWQxLnRlbmFuY3kub2MxLi5hYWFhYWFhYV9leGFtcGxl"
)

func setUp(secret *v1.Secret, setClient bool) *fakeclientset.Clientset {
client := fakeclientset.NewSimpleClientset()
if setClient {
action := "get"
resource := "secrets"
obj := secret
util.FakeClientGetCall(client, action, resource, obj)
}
return client
}

func TestGetConfigurationProviderSuccess(t *testing.T) {
RegisterTestingT(t)
ctx := context.TODO()
opts := types.IngressOpts{
AuthType: "user",
AuthSecretName: "oci-config",
}
configName := "config"
privateKey := "private-key"
secret := util.GetSampleSecret(configName, privateKey, data, PrivateKey)
client := setUp(secret, true)

auth, err := GetConfigurationProvider(ctx, opts, client)
Expect(auth != nil).Should(BeTrue())
Expect(err).Should(BeNil())
}

func TestGetConfigurationProviderFailSecret(t *testing.T) {
RegisterTestingT(t)
ctx := context.TODO()
opts := types.IngressOpts{
AuthType: "user",
AuthSecretName: "oci-config",
}
secret := util.GetSampleSecret("test", "error", data, PrivateKey)

client := setUp(secret, false)
auth, err := GetConfigurationProvider(ctx, opts, client)
Expect(auth == nil).Should(BeTrue())
Expect(err != nil).Should(BeTrue())
Expect(err.Error()).Should(Equal("error retrieving secret: oci-config"))

client = setUp(secret, true)
auth, err = GetConfigurationProvider(ctx, opts, client)
Expect(auth == nil).Should(BeTrue())
Expect(err != nil).Should(BeTrue())
Expect(err.Error()).Should(Equal("auth config data is empty: oci-config"))

secret = util.GetSampleSecret("config", "error", data, PrivateKey)
client = setUp(secret, true)
auth, err = GetConfigurationProvider(ctx, opts, client)
Expect(auth == nil).Should(BeTrue())
Expect(err != nil).Should(BeTrue())
Expect(err.Error()).Should(Equal("missing auth config data: invalid user auth config data: oci-config"))

secret = util.GetSampleSecret("configs", "error", data, PrivateKey)
client = setUp(secret, true)
auth, err = GetConfigurationProvider(ctx, opts, client)
Expect(auth == nil).Should(BeTrue())
Expect(err != nil).Should(BeTrue())
Expect(err.Error()).Should(Equal("auth config data is empty: oci-config"))
}

func TestRetrieveAuthConfigInstanceAuthType(t *testing.T) {
RegisterTestingT(t)
opts := types.IngressOpts{
AuthType: "instance",
}
cfg, err := RetrieveAuthConfig(context.TODO(), opts, "test")
cfg, err := RetrieveAuthConfig(context.TODO(), opts, "test", nil)
Expect(err == nil).Should(BeTrue())
Expect(cfg.Type).Should(Equal(types.Instance))

Expand All @@ -33,15 +98,17 @@ func TestRetrieveAuthConfigInstanceAuthTypeTestRetrieveAuthConfigInvalidAuthType
opts := types.IngressOpts{
AuthType: authType,
}
_, err := RetrieveAuthConfig(context.TODO(), opts, "test")
_, err := RetrieveAuthConfig(context.TODO(), opts, "test", nil)
Expect(err != nil).Should(BeTrue())
Expect(err.Error()).Should(Equal(fmt.Sprintf("invalid auth principal type, %s", authType)))

}

func TestParseAuthConfig(t *testing.T) {
RegisterTestingT(t)
secret := getSampleSecret()
configName := "config"
privateKey := "private-key"
secret := util.GetSampleSecret(configName, privateKey, data, PrivateKey)
authCfg, err := ParseAuthConfig(secret, "oci-config")
Expect(err == nil).Should(BeTrue())
Expect(authCfg.TenancyID).Should(Equal("ocid1.tenancy.oc1..aaaaaaaa_example"))
Expand All @@ -52,17 +119,30 @@ func TestParseAuthConfig(t *testing.T) {
Expect(err == nil).Should(BeTrue())
}

func getSampleSecret() *v1.Secret {
dat, _ := base64.StdEncoding.DecodeString(data)
secret := &v1.Secret{
ObjectMeta: metav1.ObjectMeta{
Namespace: "test",
Name: "oci-config",
},
Data: map[string][]byte{
"config": []byte(dat),
"private-key": []byte(PrivateKey),
},
}
return secret
func TestParseAuthConfigWithError(t *testing.T) {
RegisterTestingT(t)
secret := util.GetSampleSecret("error", "", data, PrivateKey)
_, err := ParseAuthConfig(secret, "oci-configs")
Expect(err != nil).Should(BeTrue())
Expect(err.Error()).Should(Equal("invalid auth config data: oci-configs"))

secret = util.GetSampleSecret("config", "", data, PrivateKey)
_, err = ParseAuthConfig(secret, "oci-configs")
Expect(err != nil).Should(BeTrue())
Expect(err.Error()).Should(Equal("invalid user auth config data: oci-configs"))

}

func TestSetHTTPClientTimeout(t *testing.T) {
RegisterTestingT(t)
timeout := setHTTPClientTimeout(httpClientTimeout)
Expect(timeout != nil).Should(Equal(true))
dis, err := timeout(&http.Client{})
Expect(dis).Should(Not(BeNil()))
Expect(err).Should(BeNil())

dis, err = timeout(nil)
Expect(dis).Should(BeNil())
Expect(err).Should(Not(BeNil()))
Expect(err.Error()).Should(Equal("unable to modify unknown HTTP client type"))
}
Loading

0 comments on commit af092f4

Please sign in to comment.