Skip to content

Commit

Permalink
Verify CRD's condition to ensure it's registered with k8s API
Browse files Browse the repository at this point in the history
OLM needs to verify CRD's condition to make sure it is registered
with k8s API during CSV control loop before installing operator.
This verification will help to avoid errors related to the
unavailability of an API when installing an operator via OLM.

Jira: https://jira.coreos.com/browse/ALM-775

Signed-off-by: Vu Dinh <vdinh@redhat.com>
  • Loading branch information
dinhxuanvu committed Nov 14, 2018
1 parent 99edec4 commit 6e6c421
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 0 deletions.
18 changes: 18 additions & 0 deletions pkg/controller/operators/olm/requirements.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
olmErrors "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/errors"
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install"
log "github.com/sirupsen/logrus"
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

Expand Down Expand Up @@ -59,6 +60,23 @@ func (a *Operator) requirementStatus(strategyDetailsDeployment *install.Strategy
met = false
statuses = append(statuses, status)
}

// Check if CRD has succes registered with k8s API
registered := false
for _, cdt := range crd.Status.Conditions {
switch cdt.Type {
case v1beta1.Established:
if cdt.Status == v1beta1.ConditionTrue {
registered = true
}
}
}

if !registered {
status.Status = v1alpha1.RequirementStatusReasonNotPresent
met = false
statuses = append(statuses, status)
}
}

// Check for required API services
Expand Down
93 changes: 93 additions & 0 deletions test/e2e/csv_e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/json"
"fmt"
"testing"
"time"

"github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1"
"github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned"
Expand Down Expand Up @@ -312,6 +313,98 @@ func TestCreateCSVWithUnmetPermissionsCRD(t *testing.T) {

}

func TestCreateCSVWithNotReadyCRD(t *testing.T) {
defer cleaner.NotifyTestComplete(t, true)

c := newKubeClient(t)
crc := newCRClient(t)

depName := genName("dep-")

// Create dependency first (CRD)
crdPlural := genName("ins2")
crdName := crdPlural + ".cluster.com"
crd := extv1beta1.CustomResourceDefinition{
ObjectMeta: metav1.ObjectMeta{
Name: crdName,
},
Spec: extv1beta1.CustomResourceDefinitionSpec{
Group: "cluster.com",
Version: "v1alpha1",
Names: extv1beta1.CustomResourceDefinitionNames{
Plural: crdPlural,
Singular: crdPlural,
Kind: crdPlural,
ListKind: "list" + crdPlural,
},
Scope: "Namespaced",
},
}
cleanupCRD, err := createCRD(c, crd)
require.NoError(t, err)
defer cleanupCRD()

getCRD, err := c.ApiextensionsV1beta1Interface().ApiextensionsV1beta1().CustomResourceDefinitions().Get(crdName, metav1.GetOptions{})
require.NoError(t, err)

// Update CRD status to Established false
establishedCondition := extv1beta1.CustomResourceDefinitionCondition{
Type: extv1beta1.Established,
Status: extv1beta1.ConditionFalse,
Reason: "InitialNamesAccepted",
Message: "The initial names have been accepted",
}

fmt.Println("test 0")

// Update CRD condition status
for i := range getCRD.Status.Conditions {
if getCRD.Status.Conditions[i].Type == establishedCondition.Type {
fmt.Sprintf("test %s", "test")
existingCondition := &getCRD.Status.Conditions[i]
existingCondition.Status = establishedCondition.Status
existingCondition.LastTransitionTime = metav1.NewTime(time.Now())
existingCondition.Reason = establishedCondition.Reason
existingCondition.Message = establishedCondition.Message
}
}

csv := v1alpha1.ClusterServiceVersion{
TypeMeta: metav1.TypeMeta{
Kind: v1alpha1.ClusterServiceVersionKind,
APIVersion: v1alpha1.ClusterServiceVersionAPIVersion,
},
ObjectMeta: metav1.ObjectMeta{
Name: genName("csv"),
},
Spec: v1alpha1.ClusterServiceVersionSpec{
InstallStrategy: newNginxInstallStrategy(depName, nil, nil),
CustomResourceDefinitions: v1alpha1.CustomResourceDefinitions{
Owned: []v1alpha1.CRDDescription{
{
Name: crdName,
Version: "v1alpha1",
Kind: crdPlural,
DisplayName: crdName,
Description: "In the cluster",
},
},
},
},
}

cleanupCSV, err := createCSV(t, c, crc, csv, testNamespace, true)
require.NoError(t, err)
defer cleanupCSV()

_, err = fetchCSV(t, crc, csv.Name, csvPendingChecker)
require.NoError(t, err)

// Shouldn't create deployment
_, err = c.GetDeployment(testNamespace, depName)
require.Error(t, err)
}

func TestCreateCSVWithUnmetRequirementsAPIService(t *testing.T) {
defer cleaner.NotifyTestComplete(t, true)

Expand Down

0 comments on commit 6e6c421

Please sign in to comment.