Skip to content

Commit 48a1875

Browse files
Merge pull request #827 from dinhxuanvu/missing-events
fix(olm): Fix the issue with missing events due to rate limit
2 parents a1e7603 + c4928e2 commit 48a1875

File tree

2 files changed

+237
-4
lines changed

2 files changed

+237
-4
lines changed

pkg/controller/operators/olm/operator.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -891,23 +891,23 @@ func (a *Operator) transitionCSVState(in v1alpha1.ClusterServiceVersion) (out *v
891891

892892
if !met {
893893
logger.Info("requirements were not met")
894-
out.SetPhaseWithEvent(v1alpha1.CSVPhasePending, v1alpha1.CSVReasonRequirementsNotMet, "one or more requirements couldn't be found", now, a.recorder)
894+
out.SetPhaseWithEventIfChanged(v1alpha1.CSVPhasePending, v1alpha1.CSVReasonRequirementsNotMet, "one or more requirements couldn't be found", now, a.recorder)
895895
syncError = ErrRequirementsNotMet
896896
return
897897
}
898898

899899
// Check for CRD ownership conflicts
900900
if syncError = a.crdOwnerConflicts(out, a.csvSet(out.GetNamespace(), v1alpha1.CSVPhaseAny)); syncError != nil {
901901
if syncError == ErrCRDOwnerConflict {
902-
out.SetPhaseWithEventIfChanged(v1alpha1.CSVPhaseFailed, v1alpha1.CSVReasonOwnerConflict, syncError.Error(), now, a.recorder)
902+
out.SetPhaseWithEvent(v1alpha1.CSVPhaseFailed, v1alpha1.CSVReasonOwnerConflict, syncError.Error(), now, a.recorder)
903903
}
904904
return
905905
}
906906

907907
// Check for APIServices ownership conflicts
908908
if syncError = a.apiServiceOwnerConflicts(out); syncError != nil {
909909
if syncError == ErrAPIServiceOwnerConflict {
910-
out.SetPhaseWithEventIfChanged(v1alpha1.CSVPhaseFailed, v1alpha1.CSVReasonOwnerConflict, syncError.Error(), now, a.recorder)
910+
out.SetPhaseWithEvent(v1alpha1.CSVPhaseFailed, v1alpha1.CSVReasonOwnerConflict, syncError.Error(), now, a.recorder)
911911
}
912912
return
913913
}
@@ -950,7 +950,7 @@ func (a *Operator) transitionCSVState(in v1alpha1.ClusterServiceVersion) (out *v
950950
} else {
951951
// Set phase to failed if it's been a long time since the last transition (5 minutes)
952952
if metav1.Now().Sub(out.Status.LastTransitionTime.Time) >= 5*time.Minute {
953-
out.SetPhaseWithEventIfChanged(v1alpha1.CSVPhaseFailed, v1alpha1.CSVReasonInstallCheckFailed, fmt.Sprintf("install timeout"), now, a.recorder)
953+
out.SetPhaseWithEvent(v1alpha1.CSVPhaseFailed, v1alpha1.CSVReasonInstallCheckFailed, fmt.Sprintf("install timeout"), now, a.recorder)
954954
}
955955
}
956956

test/e2e/csv_e2e_test.go

Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,22 @@ type cleanupFunc func()
3232

3333
var immediateDeleteGracePeriod int64 = 0
3434

35+
func findLastEvent(events *corev1.EventList) (event corev1.Event) {
36+
var latestTime metav1.Time
37+
var latestInd int
38+
for i, item := range events.Items {
39+
if i != 0 {
40+
if latestTime.Before(&item.LastTimestamp) {
41+
latestTime = item.LastTimestamp
42+
latestInd = i
43+
}
44+
} else {
45+
latestTime = item.LastTimestamp
46+
}
47+
}
48+
return events.Items[latestInd]
49+
}
50+
3551
func buildCSVCleanupFunc(t *testing.T, c operatorclient.ClientInterface, crc versioned.Interface, csv v1alpha1.ClusterServiceVersion, namespace string, deleteCRDs, deleteAPIServices bool) cleanupFunc {
3652
return func() {
3753
require.NoError(t, crc.OperatorsV1alpha1().ClusterServiceVersions(namespace).Delete(csv.GetName(), &metav1.DeleteOptions{}))
@@ -2720,4 +2736,221 @@ func TestUpdateCSVModifyDeploymentName(t *testing.T) {
27202736
require.NoError(t, err)
27212737
}
27222738

2739+
func TestCreateCSVRequirementsEvents(t *testing.T) {
2740+
defer cleaner.NotifyTestComplete(t, true)
2741+
2742+
c := newKubeClient(t)
2743+
crc := newCRClient(t)
2744+
2745+
sa := corev1.ServiceAccount{}
2746+
sa.SetName(genName("sa-"))
2747+
sa.SetNamespace(testNamespace)
2748+
_, err := c.CreateServiceAccount(&sa)
2749+
require.NoError(t, err, "could not create ServiceAccount")
2750+
2751+
permissions := []install.StrategyDeploymentPermissions{
2752+
{
2753+
ServiceAccountName: sa.GetName(),
2754+
Rules: []rbacv1.PolicyRule{
2755+
{
2756+
Verbs: []string{"create"},
2757+
APIGroups: []string{""},
2758+
Resources: []string{"deployment"},
2759+
},
2760+
{
2761+
Verbs: []string{"delete"},
2762+
APIGroups: []string{""},
2763+
Resources: []string{"deployment"},
2764+
},
2765+
},
2766+
},
2767+
}
2768+
2769+
clusterPermissions := []install.StrategyDeploymentPermissions{
2770+
{
2771+
ServiceAccountName: sa.GetName(),
2772+
Rules: []rbacv1.PolicyRule{
2773+
{
2774+
Verbs: []string{"get"},
2775+
APIGroups: []string{""},
2776+
Resources: []string{"deployment"},
2777+
},
2778+
},
2779+
},
2780+
}
2781+
2782+
depName := genName("dep-")
2783+
csv := v1alpha1.ClusterServiceVersion{
2784+
TypeMeta: metav1.TypeMeta{
2785+
Kind: v1alpha1.ClusterServiceVersionKind,
2786+
APIVersion: v1alpha1.ClusterServiceVersionAPIVersion,
2787+
},
2788+
ObjectMeta: metav1.ObjectMeta{
2789+
Name: genName("csv"),
2790+
},
2791+
Spec: v1alpha1.ClusterServiceVersionSpec{
2792+
MinKubeVersion: "0.0.0",
2793+
InstallModes: []v1alpha1.InstallMode{
2794+
{
2795+
Type: v1alpha1.InstallModeTypeOwnNamespace,
2796+
Supported: true,
2797+
},
2798+
{
2799+
Type: v1alpha1.InstallModeTypeSingleNamespace,
2800+
Supported: true,
2801+
},
2802+
{
2803+
Type: v1alpha1.InstallModeTypeMultiNamespace,
2804+
Supported: true,
2805+
},
2806+
{
2807+
Type: v1alpha1.InstallModeTypeAllNamespaces,
2808+
Supported: true,
2809+
},
2810+
},
2811+
InstallStrategy: newNginxInstallStrategy(depName, permissions, clusterPermissions),
2812+
// Cheating a little; this is an APIservice that will exist for the e2e tests
2813+
APIServiceDefinitions: v1alpha1.APIServiceDefinitions{
2814+
Required: []v1alpha1.APIServiceDescription{
2815+
{
2816+
Group: "packages.operators.coreos.com",
2817+
Version: "v1",
2818+
Kind: "PackageManifest",
2819+
DisplayName: "Package Manifest",
2820+
Description: "An apiservice that exists",
2821+
},
2822+
},
2823+
},
2824+
},
2825+
}
2826+
2827+
// Create Role/Cluster Roles and RoleBindings
2828+
role := rbacv1.Role{
2829+
Rules: []rbacv1.PolicyRule{
2830+
{
2831+
Verbs: []string{"create"},
2832+
APIGroups: []string{""},
2833+
Resources: []string{"deployment"},
2834+
},
2835+
{
2836+
Verbs: []string{"delete"},
2837+
APIGroups: []string{""},
2838+
Resources: []string{"deployment"},
2839+
},
2840+
},
2841+
}
2842+
role.SetName("test-role")
2843+
role.SetNamespace(testNamespace)
2844+
_, err = c.CreateRole(&role)
2845+
require.NoError(t, err, "could not create Role")
2846+
2847+
roleBinding := rbacv1.RoleBinding{
2848+
Subjects: []rbacv1.Subject{
2849+
{
2850+
Kind: "ServiceAccount",
2851+
APIGroup: "",
2852+
Name: sa.GetName(),
2853+
Namespace: sa.GetNamespace(),
2854+
},
2855+
},
2856+
RoleRef: rbacv1.RoleRef{
2857+
APIGroup: "rbac.authorization.k8s.io",
2858+
Kind: "Role",
2859+
Name: role.GetName(),
2860+
},
2861+
}
2862+
roleBinding.SetName(genName("dep-"))
2863+
roleBinding.SetNamespace(testNamespace)
2864+
_, err = c.CreateRoleBinding(&roleBinding)
2865+
require.NoError(t, err, "could not create RoleBinding")
2866+
2867+
clusterRole := rbacv1.ClusterRole{
2868+
Rules: []rbacv1.PolicyRule{
2869+
{
2870+
Verbs: []string{"get"},
2871+
APIGroups: []string{""},
2872+
Resources: []string{"deployment"},
2873+
},
2874+
},
2875+
}
2876+
clusterRole.SetName(genName("dep-"))
2877+
_, err = c.CreateClusterRole(&clusterRole)
2878+
require.NoError(t, err, "could not create ClusterRole")
2879+
2880+
clusterRoleBinding := rbacv1.ClusterRoleBinding{
2881+
Subjects: []rbacv1.Subject{
2882+
{
2883+
Kind: "ServiceAccount",
2884+
APIGroup: "",
2885+
Name: sa.GetName(),
2886+
Namespace: sa.GetNamespace(),
2887+
},
2888+
},
2889+
RoleRef: rbacv1.RoleRef{
2890+
APIGroup: "rbac.authorization.k8s.io",
2891+
Kind: "ClusterRole",
2892+
Name: clusterRole.GetName(),
2893+
},
2894+
}
2895+
clusterRoleBinding.SetName(genName("dep-"))
2896+
_, err = c.CreateClusterRoleBinding(&clusterRoleBinding)
2897+
require.NoError(t, err, "could not create ClusterRoleBinding")
2898+
2899+
cleanupCSV, err := createCSV(t, c, crc, csv, testNamespace, false, false)
2900+
require.NoError(t, err)
2901+
defer cleanupCSV()
2902+
2903+
_, err = fetchCSV(t, crc, csv.Name, testNamespace, csvSucceededChecker)
2904+
require.NoError(t, err)
2905+
2906+
listOptions := metav1.ListOptions{
2907+
FieldSelector: "involvedObject.kind=ClusterServiceVersion",
2908+
}
2909+
2910+
// Get events from test namespace for CSV
2911+
eventsList, err := c.KubernetesInterface().CoreV1().Events(testNamespace).List(listOptions)
2912+
require.NoError(t, err)
2913+
latestEvent := findLastEvent(eventsList)
2914+
require.Equal(t, string(latestEvent.Reason), "InstallSucceeded")
2915+
2916+
// Edit role
2917+
updatedRole := rbacv1.Role{
2918+
Rules: []rbacv1.PolicyRule{
2919+
{
2920+
Verbs: []string{"create"},
2921+
APIGroups: []string{""},
2922+
Resources: []string{"deployment"},
2923+
},
2924+
},
2925+
}
2926+
updatedRole.SetName("test-role")
2927+
updatedRole.SetNamespace(testNamespace)
2928+
_, err = c.UpdateRole(&updatedRole)
2929+
require.NoError(t, err)
2930+
2931+
// Check CSV status
2932+
_, err = fetchCSV(t, crc, csv.Name, testNamespace, csvPendingChecker)
2933+
require.NoError(t, err)
2934+
2935+
// Check event
2936+
eventsList, err = c.KubernetesInterface().CoreV1().Events(testNamespace).List(listOptions)
2937+
require.NoError(t, err)
2938+
latestEvent = findLastEvent(eventsList)
2939+
require.Equal(t, string(latestEvent.Reason), "RequirementsNotMet")
2940+
2941+
// Reverse the updated role
2942+
_, err = c.UpdateRole(&role)
2943+
require.NoError(t, err)
2944+
2945+
// Check CSV status
2946+
_, err = fetchCSV(t, crc, csv.Name, testNamespace, csvSucceededChecker)
2947+
require.NoError(t, err)
2948+
2949+
// Check event
2950+
eventsList, err = c.KubernetesInterface().CoreV1().Events(testNamespace).List(listOptions)
2951+
require.NoError(t, err)
2952+
latestEvent = findLastEvent(eventsList)
2953+
require.Equal(t, string(latestEvent.Reason), "InstallSucceeded")
2954+
}
2955+
27232956
// TODO: test behavior when replaces field doesn't point to existing CSV

0 commit comments

Comments
 (0)