diff --git a/Makefile b/Makefile index 364de40a9..cd7ccd2a4 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ GOLANGCI_LINT_VERSION:=v1.43.0 OPM_VERSION:=v1.24.0 # Build Flags -export CGO_ENABLED:=1 +export CGO_ENABLED:=0 BRANCH=$(shell git rev-parse --abbrev-ref HEAD) SHORT_SHA=$(shell git rev-parse --short HEAD) VERSION?=${SHORT_SHA} diff --git a/apis/addons/v1alpha1/addons_types.go b/apis/addons/v1alpha1/addons_types.go index 1ee99cbbb..8ac2ef953 100644 --- a/apis/addons/v1alpha1/addons_types.go +++ b/apis/addons/v1alpha1/addons_types.go @@ -319,8 +319,11 @@ const ( // Addon has timed out waiting for acknowledgement from the underlying addon. AddonReasonDeletionTimedOut = "AddonReasonDeletionTimedOut" - // Addon Instance is not yet installed. + // Addon instance is not yet installed. AddonReasonInstanceNotInstalled = "AddonInstanceNotInstalled" + + // Addon instance has been successfully installed. + AddonReasonInstanceInstalled = "AddonInstanceInstalled" ) type AddonNamespace struct { diff --git a/integration/addon_test.go b/integration/addon_test.go index 68523ee04..0457c3db3 100644 --- a/integration/addon_test.go +++ b/integration/addon_test.go @@ -407,6 +407,88 @@ func (s *integrationTestSuite) TestAddonConditions() { s.Require().Equal(addonsv1alpha1.AddonReasonMissingCSV, availableCond.Reason) }) + s.Run("sets_installed=true_with_install_ack_required", func() { + // Remove addon before starting the test. + s.addonCleanup(addon, ctx) + + addon := addonWithInstallAck() + + err := integration.Client.Create(ctx, addon) + s.Require().NoError(err) + + addonCSV := &operatorsv1alpha1.ClusterServiceVersion{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "namespace-onbgdions", + Name: "reference-addon.v0.1.0", + }, + } + + // Assert that the csv phase has succeeded while the + // addon is being installed. + err = integration.WaitForObject( + ctx, + s.T(), defaultAddonAvailabilityTimeout, addonCSV, "to have succeeded phase", + func(obj client.Object) (done bool, err error) { + csv := obj.(*operatorsv1alpha1.ClusterServiceVersion) + return csv.Status.Phase == operatorsv1alpha1.CSVPhaseSucceeded, nil + }) + s.Require().NoError(err) + + err = integration.Client.Get(ctx, client.ObjectKeyFromObject(addon), addon) + s.Require().NoError(err) + + // Assert that the addon's installed condition is false. + // i.e. even though the csv phase has succeeded, addon doesn't report as installed. + s.Require().True(meta.IsStatusConditionFalse(addon.Status.Conditions, addonsv1alpha1.Installed)) + + instance := &addonsv1alpha1.AddonInstance{} + err = integration.Client.Get(ctx, types.NamespacedName{ + Name: addonsv1alpha1.DefaultAddonInstanceName, + Namespace: addon.Spec.Install.OLMOwnNamespace.Namespace, + }, instance) + s.Require().NoError(err) + + // Assert 'Installed' condition is not present in addon instance. + s.Require().Nil(meta.FindStatusCondition(instance.Status.Conditions, addonsv1alpha1.AddonInstanceConditionInstalled.String())) + + // We impersonate the addon's operator and report its addon instance as installed. + meta.SetStatusCondition(&instance.Status.Conditions, metav1.Condition{ + Type: addonsv1alpha1.AddonInstanceConditionInstalled.String(), + Reason: addonsv1alpha1.AddonReasonInstanceInstalled, + Message: "Addon instance is installed", + Status: metav1.ConditionTrue, + }) + + err = integration.Client.Status().Update(ctx, instance) + s.Require().NoError(err) + + // Wait until addon has installed=true. + // i.e. Addon Instance has been installed & CSV phase has succeeded. + err = integration.WaitForObject( + ctx, + s.T(), defaultAddonAvailabilityTimeout, addon, "to be installed", + func(obj client.Object) (done bool, err error) { + a := obj.(*addonsv1alpha1.Addon) + return meta.IsStatusConditionTrue( + a.Status.Conditions, addonsv1alpha1.Installed), nil + }) + s.Require().NoError(err) + + err = integration.Client.Get(ctx, client.ObjectKeyFromObject(addon), addon) + s.Require().NoError(err) + + // Assert that the required conditions are met. + instanceInstalledCond := meta.FindStatusCondition(instance.Status.Conditions, addonsv1alpha1.AddonInstanceConditionInstalled.String()) + s.Require().NotNil(instanceInstalledCond) + s.Require().Equal(metav1.ConditionTrue, instanceInstalledCond.Status) + availableCond := meta.FindStatusCondition(addon.Status.Conditions, addonsv1alpha1.Available) + s.Require().NotNil(availableCond) + s.Require().Equal(metav1.ConditionTrue, availableCond.Status) + addonInstalledCond := meta.FindStatusCondition(addon.Status.Conditions, addonsv1alpha1.Installed) + s.Require().NotNil(addonInstalledCond) + s.Require().Equal(metav1.ConditionTrue, addonInstalledCond.Status) + }) + s.T().Cleanup(func() { s.addonCleanup(addon, ctx) }) diff --git a/integration/fixtures_test.go b/integration/fixtures_test.go index 08b000538..5e1f10a01 100644 --- a/integration/fixtures_test.go +++ b/integration/fixtures_test.go @@ -114,10 +114,8 @@ func addonWithVersion(version string, catalogSrc string) *addonsv1alpha1.Addon { }, Spec: addonsv1alpha1.AddonSpec{ DeleteAckRequired: true, - // TODO: Modify reference-addon to report addon instance as installed without depending on the addon's availability - // InstallAckRequired: true, - Version: version, - DisplayName: "addon-oisafbo12", + Version: version, + DisplayName: "addon-oisafbo12", Namespaces: []addonsv1alpha1.AddonNamespace{ {Name: "namespace-onbgdions"}, {Name: "namespace-pioghfndb"}, @@ -140,6 +138,38 @@ func addonWithVersion(version string, catalogSrc string) *addonsv1alpha1.Addon { } } +func addonWithInstallAck() *addonsv1alpha1.Addon { + return &addonsv1alpha1.Addon{ + ObjectMeta: metav1.ObjectMeta{ + Name: "addon-oisafbo12", + }, + Spec: addonsv1alpha1.AddonSpec{ + DeleteAckRequired: true, + InstallAckRequired: true, + Version: "v0.1.0", + DisplayName: "addon-oisafbo12", + Namespaces: []addonsv1alpha1.AddonNamespace{ + {Name: "namespace-onbgdions"}, + {Name: "namespace-pioghfndb"}, + }, + Install: addonsv1alpha1.AddonInstallSpec{ + Type: addonsv1alpha1.OLMOwnNamespace, + OLMOwnNamespace: &addonsv1alpha1.AddonInstallOLMOwnNamespace{ + AddonInstallOLMCommon: addonsv1alpha1.AddonInstallOLMCommon{ + Namespace: "namespace-onbgdions", + CatalogSourceImage: referenceAddonCatalogSourceImageWorking, + Channel: "alpha", + PackageName: "reference-addon", + Config: &addonsv1alpha1.SubscriptionConfig{ + EnvironmentVariables: referenceAddonConfigEnvObjects, + }, + }, + }, + }, + }, + } +} + func addonWithAdditionalCatalogSource() *addonsv1alpha1.Addon { return &addonsv1alpha1.Addon{ ObjectMeta: metav1.ObjectMeta{