Skip to content

Commit

Permalink
add e2e test
Browse files Browse the repository at this point in the history
and include fixes for bugs discovered
  • Loading branch information
Jeff Peeler committed Oct 12, 2018
1 parent 33d32f8 commit bb9d5fa
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 33 deletions.
76 changes: 45 additions & 31 deletions pkg/controller/operators/olm/operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -295,9 +295,7 @@ func (a *Operator) syncRBAC(obj interface{}) (syncError error) {
}

func namespacesChanged(clusterNamespaces []corev1.Namespace, statusNamespaces []corev1.Namespace) bool {
nsCount := len(clusterNamespaces)

if len(statusNamespaces) != nsCount {
if len(clusterNamespaces) != len(statusNamespaces) {
return true
}

Expand Down Expand Up @@ -329,11 +327,16 @@ func (a *Operator) updateDeploymentAnnotation(op *v1alpha2.OperatorGroup) (error

if !namespacesChanged(namespaceList.Items, op.Status.Namespaces) {
// status is current with correct namespaces, so no further updates required
log.Debugf("No namespace changes detected, found: %v", namespaceList.Items)
return nil, namespaceList.Items
}
op.Status.Namespaces = namespaceList.Items
log.Debugf("Namespace change detected, found: %v", namespaceList.Items)
op.Status.Namespaces = make([]corev1.Namespace, len(namespaceList.Items))
copy(op.Status.Namespaces, namespaceList.Items)
op.Status.LastUpdated = timeNow()
_, err = a.client.OperatorsV1alpha2().OperatorGroups(op.Namespace).UpdateStatus(op)
if err != nil {
return err, namespaceList.Items
}

currentNamespace := op.GetNamespace()
csvsInNamespace := a.csvsInNamespace(currentNamespace)
Expand All @@ -350,13 +353,14 @@ func (a *Operator) updateDeploymentAnnotation(op *v1alpha2.OperatorGroup) (error
apiEditPolicyRules = append(apiEditPolicyRules, rbacv1.PolicyRule{Verbs: []string{"create", "update", "patch", "delete"}, APIGroups: []string{owned.Name}, Resources: []string{owned.Kind}})
apiViewPolicyRules = append(apiViewPolicyRules, rbacv1.PolicyRule{Verbs: []string{"get", "list", "watch"}, APIGroups: []string{owned.Name}, Resources: []string{owned.Kind}})
}
for _, owned := range csv.Spec.APIServiceDefinitions.Owned {
resourceNames := []string{}
for _, resource := range owned.Resources {
resourceNames = append(resourceNames, resource.Name)
}
managerPolicyRules = append(managerPolicyRules, rbacv1.PolicyRule{Verbs: []string{"*"}, APIGroups: []string{owned.Name}, Resources: resourceNames})
}
// TODO: definitely remove?
// for _, owned := range csv.Spec.APIServiceDefinitions.Owned {
// resourceNames := []string{}
// for _, resource := range owned.Resources {
// resourceNames = append(resourceNames, resource.Name)
// }
// managerPolicyRules = append(managerPolicyRules, rbacv1.PolicyRule{Verbs: []string{"*"}, APIGroups: []string{owned.Name}, Resources: resourceNames})
// }
clusterRole := &rbacv1.ClusterRole{
Rules: managerPolicyRules,
}
Expand Down Expand Up @@ -398,9 +402,7 @@ func (a *Operator) updateDeploymentAnnotation(op *v1alpha2.OperatorGroup) (error

// write above namespaces to watch in every deployment
for _, ns := range nsList {
//deploymentList, err := a.OpClient.KubernetesInterface().AppsV1().Deployments(ns).List(metav1.ListOptions{})
deploymentList, err := a.deploymentLister[ns].List(labels.Everything())
log.Debugf("JPEELER: looking at ns %v deployments:%v\n", ns, deploymentList)
if err != nil {
return err, namespaceList.Items
}
Expand Down Expand Up @@ -447,23 +449,35 @@ func (a *Operator) syncOperatorGroups(obj interface{}) error {
return err
}

for _, ns := range targetedNamespaces {
csvsInNamespace := a.csvsInNamespace(ns.Name)
for _, csv := range csvsInNamespace {
if csv.Status.Phase == v1alpha1.CSVPhaseSucceeded {
newCSV := csv.DeepCopy()
newCSV.Status = v1alpha1.ClusterServiceVersionStatus{
Message: "CSV copied to target namespace",
Reason: v1alpha1.CSVReasonCopied,
LastUpdateTime: timeNow(),
}
metav1.SetMetaDataAnnotation(&newCSV.ObjectMeta, "olm.originalCSV", fmt.Sprintf("%v/%v", csv.GetNamespace(), csv.GetName()))
ownerutil.AddNonBlockingOwner(newCSV, csv)
if newCSV.GetNamespace() != ns.Name {
_, err := a.client.OperatorsV1alpha1().ClusterServiceVersions(newCSV.GetNamespace()).Create(newCSV)
if err != nil {
return err
}
csvsInNamespace := a.csvsInNamespace(op.Namespace)
for _, csv := range csvsInNamespace {
// TODO: handle CSV copying in a different place
// if csv.Status.Phase != v1alpha1.CSVPhaseSucceeded {
// log.Debugf("JPEELER: continuing on, skipping CSV %v\n", csv.Name)
// continue
// }

// create new CSV instead of DeepCopy as namespace and resource version (and status) will be different
newCSV := v1alpha1.ClusterServiceVersion{
ObjectMeta: metav1.ObjectMeta{
Name: csv.Name,
},
Spec: *csv.Spec.DeepCopy(),
Status: v1alpha1.ClusterServiceVersionStatus{
Message: "CSV copied to target namespace",
Reason: v1alpha1.CSVReasonCopied,
LastUpdateTime: timeNow(),
},
}

metav1.SetMetaDataAnnotation(&newCSV.ObjectMeta, "olm.originalCSV", fmt.Sprintf("%v/%v", csv.GetNamespace(), csv.GetName()))
ownerutil.AddNonBlockingOwner(&newCSV, csv)
for _, ns := range targetedNamespaces {
newCSV.SetNamespace(ns.Name)
if ns.Name != op.Namespace {
_, err := a.client.OperatorsV1alpha1().ClusterServiceVersions(newCSV.GetNamespace()).Create(&newCSV)
if err != nil {
return err
}
}
}
Expand Down
6 changes: 4 additions & 2 deletions pkg/controller/operators/olm/operator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1031,7 +1031,7 @@ func TestTransitionCSV(t *testing.T) {
}

func TestSyncOperatorGroups(t *testing.T) {
log.SetLevel(log.DebugLevel)
//log.SetLevel(log.DebugLevel)

nowTime := metav1.Date(2006, time.January, 2, 15, 4, 5, 0, time.FixedZone("MST", -7*3600))
timeNow = func() metav1.Time { return nowTime }
Expand Down Expand Up @@ -1076,7 +1076,6 @@ func TestSyncOperatorGroups(t *testing.T) {
ObjectMeta: metav1.ObjectMeta{
Name: "operator-group-1",
Namespace: testNS,
Labels: map[string]string{"app": "matchLabel"},
},
Spec: v1alpha2.OperatorGroupSpec{
Selector: metav1.LabelSelector{
Expand Down Expand Up @@ -1240,6 +1239,9 @@ func TestSyncOperatorGroups(t *testing.T) {
informerFactory.Start(stopCh)
informerFactory.WaitForCacheSync(stopCh)

// Could not put this in initialObjs - got "no kind is registered for the type v1alpha2.OperatorGroup"
op.client.OperatorsV1alpha2().OperatorGroups(tc.inputGroup.Namespace).Create(&tc.inputGroup)

err = op.syncOperatorGroups(&tc.inputGroup)
require.NoError(t, err)
assert.Equal(t, tc.expectedStatus, tc.inputGroup.Status)
Expand Down
97 changes: 97 additions & 0 deletions test/e2e/operator_groups_e2e_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package e2e

import (
"testing"

"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/util/wait"

"github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1"
"github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha2"

"github.com/coreos/go-semver/semver"
log "github.com/sirupsen/logrus"
"github.com/stretchr/testify/require"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// TODO: make tests for:
// RBAC
// Deployment annotation verification

// func NoTestCreateOperatorGroupWithMatchingNamespace(t *testing.T) {
// // Create namespace with specific label
// // Create deployment in namespace
// // Create operator group that watches namespace and uses specific label
// // Verify operator group status contains correct status
// // Verify deployments have correct namespace annotation

// // c := newKubeClient(t)

// // deployment := appsv1.

// // c.CreateDeployment()

// }

func TestCreateOperatorCSVCopy(t *testing.T) {
// create operator namespace
// create operator group in OLM namespace
// create CSV in OLM namespace
// verify CSV is copied to operator namespace

log.SetLevel(log.DebugLevel)
c := newKubeClient(t)
crc := newCRClient(t)
operatorNamespaceName := testNamespace + "-operator"
csvName := "acsv-that-is-unique" // must be lowercase for DNS-1123 validation
matchingLabel := map[string]string{"app": "matchLabel"}

operatorNamespace := corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: operatorNamespaceName,
Labels: matchingLabel,
},
}
_, err := c.KubernetesInterface().CoreV1().Namespaces().Create(&operatorNamespace)
require.NoError(t, err)

operatorGroup := v1alpha2.OperatorGroup{
ObjectMeta: metav1.ObjectMeta{
Name: "e2e-operator-group",
Namespace: testNamespace,
},
Spec: v1alpha2.OperatorGroupSpec{
Selector: metav1.LabelSelector{
MatchLabels: matchingLabel,
},
},
}
_, err = crc.OperatorsV1alpha2().OperatorGroups(testNamespace).Create(&operatorGroup)
require.NoError(t, err)

aCSV := newCSV(csvName, testNamespace, "", *semver.New("0.0.0"), nil, nil, newNginxInstallStrategy("aspec", nil, nil))
createdCSV, err := crc.OperatorsV1alpha1().ClusterServiceVersions(testNamespace).Create(&aCSV)
require.NoError(t, err)

var csvCopy *v1alpha1.ClusterServiceVersion
err = wait.Poll(pollInterval, pollDuration, func() (bool, error) {
csvCopy, err = crc.OperatorsV1alpha1().ClusterServiceVersions(operatorNamespaceName).Get(csvName, metav1.GetOptions{})
if err != nil {
if errors.IsNotFound(err) {
return false, nil
}
return false, err
}
return true, nil
})
require.Equal(t, createdCSV.Name, csvCopy.Name)
require.Equal(t, createdCSV.Spec, csvCopy.Spec)

// clean up
err = c.KubernetesInterface().CoreV1().Namespaces().Delete(operatorNamespaceName, &metav1.DeleteOptions{})
if err != nil {
t.Errorf("Operator namespace cleanup failed: %v\n", err)
}
}

0 comments on commit bb9d5fa

Please sign in to comment.