@@ -2,17 +2,21 @@ package e2e
22
33import (
44 "context"
5+ "encoding/json"
56 "errors"
67 "fmt"
78 "strings"
89 "sync"
910 "time"
1011
12+ "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/catalog"
13+
1114 "github.com/operator-framework/operator-lifecycle-manager/test/e2e/ctx"
1215
1316 "github.com/blang/semver"
1417 . "github.com/onsi/ginkgo"
1518 "github.com/onsi/ginkgo/extensions/table"
19+ . "github.com/onsi/gomega"
1620 "github.com/stretchr/testify/assert"
1721 "github.com/stretchr/testify/require"
1822 appsv1 "k8s.io/api/apps/v1"
@@ -2623,6 +2627,94 @@ var _ = Describe("Install Plan", func() {
26232627 require .NoError (GinkgoT (), err )
26242628 log (fmt .Sprintf ("Install plan %s fetched with status %s" , fetchedInstallPlan .GetName (), fetchedInstallPlan .Status .Phase ))
26252629 })
2630+
2631+ It ("compresses installplan step resource manifests to configmap references" , func () {
2632+ // Test ensures that all steps for index-based catalogs are references to configmaps. This avoids the problem
2633+ // of installplans growing beyond the etcd size limit when manifests are written to the ip status.
2634+
2635+ c := newKubeClient ()
2636+ crc := newCRClient ()
2637+
2638+ ns , err := c .KubernetesInterface ().CoreV1 ().Namespaces ().Create (context .TODO (), & corev1.Namespace {
2639+ ObjectMeta : metav1.ObjectMeta {
2640+ Name : genName ("ns-" ),
2641+ },
2642+ }, metav1.CreateOptions {})
2643+ Expect (err ).ToNot (HaveOccurred ())
2644+
2645+ og := & operatorsv1.OperatorGroup {}
2646+ og .SetName ("og" )
2647+ _ , err = crc .OperatorsV1 ().OperatorGroups (ns .GetName ()).Create (context .TODO (), og , metav1.CreateOptions {})
2648+ Expect (err ).ToNot (HaveOccurred ())
2649+
2650+ deleteOpts := & metav1.DeleteOptions {}
2651+ defer c .KubernetesInterface ().CoreV1 ().Namespaces ().Delete (context .TODO (), ns .GetName (), * deleteOpts )
2652+
2653+ catsrc := & operatorsv1alpha1.CatalogSource {
2654+ ObjectMeta : metav1.ObjectMeta {
2655+ Name : genName ("kiali-" ),
2656+ Namespace : ns .GetName (),
2657+ Labels : map [string ]string {"olm.catalogSource" : "kaili-catalog" },
2658+ },
2659+ Spec : operatorsv1alpha1.CatalogSourceSpec {
2660+ Image : "quay.io/olmtest/single-bundle-index:1.0.0" ,
2661+ SourceType : operatorsv1alpha1 .SourceTypeGrpc ,
2662+ },
2663+ }
2664+ catsrc , err = crc .OperatorsV1alpha1 ().CatalogSources (catsrc .GetNamespace ()).Create (context .TODO (), catsrc , metav1.CreateOptions {})
2665+ Expect (err ).ToNot (HaveOccurred ())
2666+
2667+ // Wait for the CatalogSource to be ready
2668+ catsrc , err = fetchCatalogSourceOnStatus (crc , catsrc .GetName (), catsrc .GetNamespace (), catalogSourceRegistryPodSynced )
2669+ Expect (err ).ToNot (HaveOccurred ())
2670+
2671+ // Generate a Subscription
2672+ subName := genName ("kiali-" )
2673+ createSubscriptionForCatalog (crc , catsrc .GetNamespace (), subName , catsrc .GetName (), "kiali" , stableChannel , "" , operatorsv1alpha1 .ApprovalAutomatic )
2674+
2675+ sub , err := fetchSubscription (crc , catsrc .GetNamespace (), subName , subscriptionHasInstallPlanChecker )
2676+ Expect (err ).ToNot (HaveOccurred ())
2677+
2678+ // Wait for the expected InstallPlan's execution to either fail or succeed
2679+ ipName := sub .Status .InstallPlanRef .Name
2680+ ip , err := waitForInstallPlan (crc , ipName , sub .GetNamespace (), buildInstallPlanPhaseCheckFunc (operatorsv1alpha1 .InstallPlanPhaseFailed , operatorsv1alpha1 .InstallPlanPhaseComplete ))
2681+ Expect (err ).ToNot (HaveOccurred ())
2682+ Expect (operatorsv1alpha1 .InstallPlanPhaseComplete ).To (Equal (ip .Status .Phase ), "InstallPlan not complete" )
2683+
2684+ // Ensure the InstallPlan contains the steps resolved from the bundle image
2685+ operatorName := "kiali-operator"
2686+ expectedSteps := map [registry.ResourceKey ]struct {}{
2687+ {Name : operatorName , Kind : "ClusterServiceVersion" }: {},
2688+ {Name : "kialis.kiali.io" , Kind : "CustomResourceDefinition" }: {},
2689+ {Name : "monitoringdashboards.monitoring.kiali.io" , Kind : "CustomResourceDefinition" }: {},
2690+ {Name : operatorName , Kind : "ServiceAccount" }: {},
2691+ {Name : operatorName , Kind : "ClusterRole" }: {},
2692+ {Name : operatorName , Kind : "ClusterRoleBinding" }: {},
2693+ }
2694+ Expect (ip .Status .Plan ).To (HaveLen (len (expectedSteps )), "number of expected steps does not match installed: %v" , ip .Status .Plan )
2695+
2696+ for _ , step := range ip .Status .Plan {
2697+ key := registry.ResourceKey {
2698+ Name : step .Resource .Name ,
2699+ Kind : step .Resource .Kind ,
2700+ }
2701+ for expected := range expectedSteps {
2702+ if strings .HasPrefix (key .Name , expected .Name ) && key .Kind == expected .Kind {
2703+ delete (expectedSteps , expected )
2704+ }
2705+ }
2706+ }
2707+ Expect (expectedSteps ).To (HaveLen (0 ), "Actual resource steps do not match expected: %#v" , expectedSteps )
2708+
2709+ // Ensure that all the steps have a configmap based reference
2710+ for _ , step := range ip .Status .Plan {
2711+ manifest := step .Resource .Manifest
2712+ var ref catalog.UnpackedBundleReference
2713+ err := json .Unmarshal ([]byte (manifest ), & ref )
2714+ Expect (err ).ToNot (HaveOccurred ())
2715+ Expect (ref .Kind ).To (Equal ("ConfigMap" ))
2716+ }
2717+ })
26262718})
26272719
26282720type checkInstallPlanFunc func (fip * operatorsv1alpha1.InstallPlan ) bool
0 commit comments