Skip to content

Commit

Permalink
Implementation for cluster identity
Browse files Browse the repository at this point in the history
  • Loading branch information
shyamradhakrishnan committed Jan 31, 2023
1 parent 55cbaf2 commit 2bd141e
Show file tree
Hide file tree
Showing 6 changed files with 413 additions and 3 deletions.
39 changes: 39 additions & 0 deletions cloud/util/suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
Copyright (c) 2021, 2022 Oracle and/or its affiliates.
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
https://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 util

import (
"os"
"testing"

infrastructurev1beta1 "github.com/oracle/cluster-api-provider-oci/api/v1beta1"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/client-go/kubernetes/scheme"
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
)

func TestMain(m *testing.M) {
code := 0
defer func() { os.Exit(code) }()
setup()
code = m.Run()
}

func setup() {
utilruntime.Must(infrastructurev1beta1.AddToScheme(scheme.Scheme))
utilruntime.Must(clusterv1.AddToScheme(scheme.Scheme))
}
4 changes: 2 additions & 2 deletions cloud/util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ func InitClientsAndRegion(ctx context.Context, client client.Client, defaultRegi
// 2) If region is set in the cluster identity, that takes the next priority
// 3) Last priority is for region set at the Pod initialization time OCI identity
clusterRegion := defaultRegion

identityRef := clusterAccessor.GetIdentityRef()
// If Cluster identity is set, OCI Clients should be created using the identity
if identityRef != nil {
Expand All @@ -163,7 +163,7 @@ func InitClientsAndRegion(ctx context.Context, client client.Client, defaultRegi
clusterRegion = clusterAccessor.GetRegion()
}
if len(clusterRegion) <= 0 {
return nil, "", scope.OCIClients{}, errors.New("RegionIdentifier could not be identified")
return nil, "", scope.OCIClients{}, errors.New("OCI Region could not be identified for the cluster")
}
clients, err := clientProvider.GetOrBuildClient(clusterRegion)
if err != nil {
Expand Down
300 changes: 300 additions & 0 deletions cloud/util/util_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,300 @@
/*
Copyright (c) 2021, 2022 Oracle and/or its affiliates.
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
https://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 util

import (
"context"
"reflect"
"testing"

. "github.com/onsi/gomega"
infrastructurev1beta1 "github.com/oracle/cluster-api-provider-oci/api/v1beta1"
"github.com/oracle/cluster-api-provider-oci/cloud/config"
"github.com/oracle/cluster-api-provider-oci/cloud/scope"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
)

func TestGetClusterIdentityFromRef(t *testing.T) {
testCases := []struct {
name string
namespace string
ref *corev1.ObjectReference
objects []client.Object
errorExpected bool
expectedSpec infrastructurev1beta1.OCIClusterIdentitySpec
}{
{
name: "simple",
namespace: "default",
ref: &corev1.ObjectReference{
Kind: "OCIClusterIdentity",
Namespace: "default",
Name: "test-identity",
APIVersion: "infrastructure.cluster.x-k8s.io/v1beta1",
},
objects: []client.Object{&infrastructurev1beta1.OCIClusterIdentity{
ObjectMeta: metav1.ObjectMeta{
Name: "test-identity",
Namespace: "default",
},
Spec: infrastructurev1beta1.OCIClusterIdentitySpec{
Type: infrastructurev1beta1.UserPrincipal,
PrincipalSecret: corev1.SecretReference{
Name: "test",
Namespace: "test",
},
},
}},
expectedSpec: infrastructurev1beta1.OCIClusterIdentitySpec{
Type: infrastructurev1beta1.UserPrincipal,
PrincipalSecret: corev1.SecretReference{
Name: "test",
Namespace: "test",
},
},
},
{
name: "error - not found",
namespace: "default",
ref: &corev1.ObjectReference{
Kind: "OCIClusterIdentity",
Namespace: "default",
Name: "test-identity",
APIVersion: "infrastructure.cluster.x-k8s.io/v1beta1",
},
objects: []client.Object{},
errorExpected: true,
},
}
for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
g := NewWithT(t)
client := fake.NewClientBuilder().WithObjects(tt.objects...).Build()
result, err := GetClusterIdentityFromRef(context.Background(), client, tt.namespace, tt.ref)
if tt.errorExpected {
g.Expect(err).To(Not(BeNil()))
} else {
g.Expect(err).To(BeNil())
if !reflect.DeepEqual(tt.expectedSpec, result.Spec) {
t.Errorf("Test (%s) \n Expected %v, \n Actual %v", tt.name, tt.expectedSpec, result.Spec)
}
}
})
}
}

func TestGetOrBuildClientFromIdentity(t *testing.T) {
testCases := []struct {
name string
namespace string
clusterIdentity *infrastructurev1beta1.OCIClusterIdentity
objects []client.Object
errorExpected bool
defaultRegion string
}{
{
name: "error - secret not found",
namespace: "default",
clusterIdentity: &infrastructurev1beta1.OCIClusterIdentity{
Spec: infrastructurev1beta1.OCIClusterIdentitySpec{
Type: infrastructurev1beta1.UserPrincipal,
PrincipalSecret: corev1.SecretReference{
Name: "test",
Namespace: "test",
},
},
},
objects: []client.Object{},
errorExpected: true,
},
{
name: "error - invalid principal type",
namespace: "default",
clusterIdentity: &infrastructurev1beta1.OCIClusterIdentity{
Spec: infrastructurev1beta1.OCIClusterIdentitySpec{
Type: "invalid",
},
},
objects: []client.Object{},
errorExpected: true,
},
{
name: "secret found",
namespace: "default",
clusterIdentity: &infrastructurev1beta1.OCIClusterIdentity{
Spec: infrastructurev1beta1.OCIClusterIdentitySpec{
Type: infrastructurev1beta1.UserPrincipal,
PrincipalSecret: corev1.SecretReference{
Name: "test",
Namespace: "test",
},
},
},
objects: []client.Object{&corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test",
},
Data: map[string][]byte{config.Tenancy: []byte("tenancy"), config.User: []byte("user"),
config.Key: []byte("key"), config.Fingerprint: []byte("fingerprint"), config.Region: []byte("region")},
}},
errorExpected: false,
},
}
for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
g := NewWithT(t)
client := fake.NewClientBuilder().WithObjects(tt.objects...).Build()
_, err := GetOrBuildClientFromIdentity(context.Background(), client, tt.clusterIdentity, tt.defaultRegion)
if tt.errorExpected {
g.Expect(err).To(Not(BeNil()))
} else {
g.Expect(err).To(BeNil())
}
})
}
}

func TestIsClusterNamespaceAllowed(t *testing.T) {
testCases := []struct {
name string
namespace string
allowedNamespaces *infrastructurev1beta1.AllowedNamespaces
objects []client.Object
expected bool
}{
{
name: "nil allowednamespace, not allowed",
namespace: "default",
objects: []client.Object{},
expected: false,
},
{
name: "empty allowednamespace, allowed",
namespace: "default",
allowedNamespaces: &infrastructurev1beta1.AllowedNamespaces{},
objects: []client.Object{},
expected: true,
},
{
name: "not allowed",
namespace: "test",
allowedNamespaces: &infrastructurev1beta1.AllowedNamespaces{
NamespaceList: []string{"test123"},
},
objects: []client.Object{},
expected: false,
},
{
name: "allowed",
namespace: "test",
allowedNamespaces: &infrastructurev1beta1.AllowedNamespaces{
NamespaceList: []string{"test"},
},
objects: []client.Object{},
expected: true,
},
{
name: "empty label selector",
namespace: "test",
allowedNamespaces: &infrastructurev1beta1.AllowedNamespaces{
Selector: &metav1.LabelSelector{},
},
objects: []client.Object{},
expected: false,
},
{
name: "allowed label selector",
namespace: "test",
allowedNamespaces: &infrastructurev1beta1.AllowedNamespaces{
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{"key": "value"},
},
},
objects: []client.Object{&corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test",
Labels: map[string]string{"key": "value"},
},
}},
expected: true,
},
}
for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
g := NewWithT(t)
client := fake.NewClientBuilder().WithObjects(tt.objects...).Build()
result := IsClusterNamespaceAllowed(context.Background(), client, tt.allowedNamespaces, tt.namespace)
g.Expect(result).To(BeEquivalentTo(tt.expected))
})
}
}

func TestCreateClientProviderFromClusterIdentity(t *testing.T) {
testCases := []struct {
name string
namespace string
objects []client.Object
clusterAccessor scope.OCIClusterAccessor
ref *corev1.ObjectReference
errorExpected bool
defaultRegion string
}{
{
name: "error - secret not found",
namespace: "default",
clusterAccessor: scope.OCISelfManagedCluster{
OCICluster: &infrastructurev1beta1.OCICluster{},
},
ref: &corev1.ObjectReference{
Kind: "OCIClusterIdentity",
Namespace: "default",
Name: "test-identity",
APIVersion: "infrastructure.cluster.x-k8s.io/v1beta1",
},
objects: []client.Object{&infrastructurev1beta1.OCIClusterIdentity{
ObjectMeta: metav1.ObjectMeta{
Name: "test-identity",
Namespace: "default",
},
Spec: infrastructurev1beta1.OCIClusterIdentitySpec{
Type: infrastructurev1beta1.UserPrincipal,
PrincipalSecret: corev1.SecretReference{
Name: "test",
Namespace: "test",
},
},
}},
errorExpected: true,
},
}
for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
g := NewWithT(t)
client := fake.NewClientBuilder().WithObjects(tt.objects...).Build()
_, err := CreateClientProviderFromClusterIdentity(context.Background(), client, tt.namespace, tt.defaultRegion, tt.clusterAccessor, tt.ref)
if tt.errorExpected {
g.Expect(err).To(Not(BeNil()))
} else {
g.Expect(err).To(BeNil())
}
})
}
}
1 change: 1 addition & 0 deletions docs/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
- [Provision a PVC on the Block Volume Service](./gs/pvc-bv.md)
- [Provision a PVC on the File Storage Service](./gs/pvc-fss.md)
- [Customize worker nodes](./gs/customize-worker-node.md)
- [Multi Tenancy](./gs/multi-tenancy.md)
- [Networking Guide](./networking/networking.md)
- [Default Network Infrastructure](./networking/infrastructure.md)
- [Using Calico](./networking/calico.md)
Expand Down
Loading

0 comments on commit 2bd141e

Please sign in to comment.