Skip to content

Commit

Permalink
add watch logic for addondeployment (#1289)
Browse files Browse the repository at this point in the history
* add watch logic for addondeployment

Signed-off-by: Coleen Iona Quadros <[email protected]>

* make sonarcloud happy

Signed-off-by: Coleen Iona Quadros <[email protected]>

* lint

Signed-off-by: Coleen Iona Quadros <[email protected]>

* refactor predicate

Signed-off-by: Coleen Iona Quadros <[email protected]>

* lint

Signed-off-by: Coleen Iona Quadros <[email protected]>

* fix test case

Signed-off-by: Coleen Iona Quadros <[email protected]>

* refactor

Signed-off-by: Coleen Iona Quadros <[email protected]>

---------

Signed-off-by: Coleen Iona Quadros <[email protected]>
  • Loading branch information
coleenquadros authored Jan 18, 2024
1 parent 2dc20cf commit 7fb7465
Show file tree
Hide file tree
Showing 6 changed files with 183 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,6 @@ func createManifestWorks(
container.Env[j].Value = strconv.FormatBool(installProm)
}
}

// If ProxyConfig is specified as part of addonConfig, set the proxy envs
if clusterName != localClusterName {
for i := range spec.Containers {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,9 @@ func (r *PlacementRuleReconciler) SetupWithManager(mgr ctrl.Manager) error {

clusterPred := getClusterPreds()

// Watch changes for AddonDeploymentConfig
AddonDeploymentPred := GetAddOnDeploymentPredicates()

obsAddonPred := predicate.Funcs{
CreateFunc: func(e event.CreateEvent) bool {
return false
Expand Down Expand Up @@ -829,6 +832,20 @@ func (r *PlacementRuleReconciler) SetupWithManager(mgr ctrl.Manager) error {
// secondary watch for alertmanager accessor serviceaccount
Watches(&source.Kind{Type: &corev1.ServiceAccount{}}, &handler.EnqueueRequestForObject{}, builder.WithPredicates(amAccessorSAPred))

// watch for AddonDeploymentConfig
if _, err := r.RESTMapper.RESTMapping(schema.GroupKind{Group: addonv1alpha1.GroupVersion.Group, Kind: "AddOnDeploymentConfig"}, addonv1alpha1.GroupVersion.Version); err == nil {
ctrBuilder = ctrBuilder.Watches(
&source.Kind{Type: &addonv1alpha1.AddOnDeploymentConfig{}},
handler.EnqueueRequestsFromMapFunc(func(obj client.Object) []reconcile.Request {
return []reconcile.Request{
{NamespacedName: types.NamespacedName{
Name: config.AddonDeploymentConfigUpdateName,
}},
}
}),
builder.WithPredicates(AddonDeploymentPred),
)
}
manifestWorkGroupKind := schema.GroupKind{Group: workv1.GroupVersion.Group, Kind: "ManifestWork"}
if _, err := r.RESTMapper.RESTMapping(manifestWorkGroupKind, workv1.GroupVersion.Version); err == nil {
workPred := getManifestworkPred()
Expand Down Expand Up @@ -937,7 +954,8 @@ func StartPlacementController(mgr manager.Manager, crdMap map[string]bool) error
func isReconcileRequired(request ctrl.Request, managedCluster string) bool {
if request.Name == config.MCOUpdatedRequestName ||
request.Name == config.MCHUpdatedRequestName ||
request.Name == config.ClusterManagementAddOnUpdateName {
request.Name == config.ClusterManagementAddOnUpdateName ||
request.Name == config.AddonDeploymentConfigUpdateName {
return true
}
if request.Namespace == config.GetDefaultNamespace() ||
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (
"strings"
"testing"

appsv1 "k8s.io/api/apps/v1"

ocinfrav1 "github.com/openshift/api/config/v1"
operatorv1 "github.com/openshift/api/operator/v1"
routev1 "github.com/openshift/api/route/v1"
Expand Down Expand Up @@ -177,7 +179,7 @@ func TestObservabilityAddonController(t *testing.T) {
},
}
objs := []runtime.Object{mco, pull, newConsoleRoute(), newTestObsApiRoute(), newTestAlertmanagerRoute(), newTestIngressController(), newTestRouteCASecret(), newCASecret(), newCertSecret(mcoNamespace), NewMetricsAllowListCM(),
NewAmAccessorSA(), NewAmAccessorTokenSecret(), newManagedClusterAddon(), deprecatedRole, newClusterMgmtAddon(),
NewAmAccessorSA(), NewAmAccessorTokenSecret(), deprecatedRole, newClusterMgmtAddon(),
newAddonDeploymentConfig(defaultAddonConfigName, namespace), newAddonDeploymentConfig(addonConfigName, namespace)}
c := fake.NewClientBuilder().WithRuntimeObjects(objs...).Build()
r := &PlacementRuleReconciler{Client: c, Scheme: s, CRDMap: map[string]bool{config.IngressControllerCRD: true}}
Expand Down Expand Up @@ -233,6 +235,68 @@ func TestObservabilityAddonController(t *testing.T) {
if err != nil {
t.Fatalf("reconcile: (%v)", err)
}
foundAddonDeploymentConfig := &addonv1alpha1.AddOnDeploymentConfig{}
err = c.Get(context.TODO(), types.NamespacedName{Namespace: namespace, Name: defaultAddonConfigName}, foundAddonDeploymentConfig)
if err != nil {
t.Fatalf("Failed to get addondeploymentconfig %s: (%v)", name, err)
}

//Change proxyconfig in addondeploymentconfig
foundAddonDeploymentConfig.Spec.ProxyConfig = addonv1alpha1.ProxyConfig{
HTTPProxy: "http://test1.com",
HTTPSProxy: "https://test1.com",
NoProxy: "test.com",
}

err = c.Update(context.TODO(), foundAddonDeploymentConfig)
if err != nil {
t.Fatalf("Failed to update addondeploymentconfig %s: (%v)", name, err)
}

req = ctrl.Request{
NamespacedName: types.NamespacedName{
Name: config.AddonDeploymentConfigUpdateName,
},
}

_, err = r.Reconcile(context.TODO(), req)
if err != nil {
t.Fatalf("reconcile after updating addondeploymentconfig: (%v)", err)
}

foundManifestwork := &workv1.ManifestWork{}
err = c.Get(context.TODO(), types.NamespacedName{Name: namespace + workNameSuffix, Namespace: namespace}, foundManifestwork)
if err != nil {
t.Fatalf("Failed to get manifestwork %s: (%v)", namespace, err)
}
for _, manifest := range foundManifestwork.Spec.Workload.Manifests {
obj, _ := util.GetObject(manifest.RawExtension)
if obj.GetObjectKind().GroupVersionKind().Kind == "Deployment" {
//Check the proxy env variables
deployment := obj.(*appsv1.Deployment)
spec := deployment.Spec.Template.Spec
for _, c := range spec.Containers {
if c.Name == "endpoint-observability-operator" {
env := c.Env
for _, e := range env {
if e.Name == "HTTP_PROXY" {
if e.Value != "http://test1.com" {
t.Fatalf("HTTP_PROXY is not set correctly: expected %s, got %s", "http://test1.com", e.Value)
}
} else if e.Name == "HTTPS_PROXY" {
if e.Value != "https://test1.com" {
t.Fatalf("HTTPS_PROXY is not set correctly: expected %s, got %s", "https://test1.com", e.Value)
}
} else if e.Name == "NO_PROXY" {
if e.Value != "test.com" {
t.Fatalf("NO_PROXY is not set correctly: expected %s, got %s", "test.com", e.Value)
}
}
}
}
}
}
}

err = c.Delete(context.TODO(), mco)
if err != nil {
Expand Down Expand Up @@ -310,7 +374,7 @@ func TestObservabilityAddonController(t *testing.T) {
// test mco-disable-alerting annotation
// 1. Verify that alertmanager-endpoint in secret hub-info-secret in the ManifestWork is not null
t.Logf("check alertmanager endpoint is not null")
foundManifestwork := &workv1.ManifestWork{}
foundManifestwork = &workv1.ManifestWork{}
err = c.Get(context.TODO(), types.NamespacedName{Name: namespace + workNameSuffix, Namespace: namespace}, foundManifestwork)
if err != nil {
t.Fatalf("Failed to get manifestwork %s: (%v)", namespace, err)
Expand Down Expand Up @@ -553,6 +617,11 @@ func newAddonDeploymentConfig(name, namespace string) *addonv1alpha1.AddOnDeploy
"kubernetes.io/os": "linux",
},
},
ProxyConfig: addonv1alpha1.ProxyConfig{
HTTPProxy: "http://foo.com",
HTTPSProxy: "https://foo.com",
NoProxy: "bar.com",
},
},
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
package placementrule

import (
"reflect"

addonv1alpha1 "open-cluster-management.io/api/addon/v1alpha1"
"sigs.k8s.io/controller-runtime/pkg/event"
"sigs.k8s.io/controller-runtime/pkg/predicate"
)
Expand Down Expand Up @@ -73,3 +76,22 @@ func getClusterPreds() predicate.Funcs {
DeleteFunc: deleteFunc,
}
}

func GetAddOnDeploymentPredicates() predicate.Funcs {
return predicate.Funcs{
CreateFunc: func(e event.CreateEvent) bool {
return true
},
UpdateFunc: func(e event.UpdateEvent) bool {
if !reflect.DeepEqual(e.ObjectNew.(*addonv1alpha1.AddOnDeploymentConfig).Spec.ProxyConfig,
e.ObjectOld.(*addonv1alpha1.AddOnDeploymentConfig).Spec.ProxyConfig) {
log.Info("AddonDeploymentConfig is updated", e.ObjectNew.GetName(), "name", e.ObjectNew.GetNamespace(), "namespace")
return true
}
return false
},
DeleteFunc: func(e event.DeleteEvent) bool {
return true
},
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (
"testing"
"time"

addonv1alpha1 "open-cluster-management.io/api/addon/v1alpha1"

appsv1 "k8s.io/api/apps/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/event"
Expand Down Expand Up @@ -146,3 +148,71 @@ func TestClusterPred(t *testing.T) {
})
}
}

func TestAddonDeploymentPredicate(t *testing.T) {
name := "test-obj"
caseList := []struct {
caseName string
namespace string
expectedCreate bool
expectedUpdate bool
expectedDelete bool
}{
{
caseName: "Create AddonDeploymentConfig",
namespace: testNamespace,
expectedCreate: true,
expectedDelete: true,
expectedUpdate: true,
},
}

defaultAddonDeploymentConfig = &addonv1alpha1.AddOnDeploymentConfig{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
},
Spec: addonv1alpha1.AddOnDeploymentConfigSpec{
ProxyConfig: addonv1alpha1.ProxyConfig{
HTTPProxy: "http://foo.com",
HTTPSProxy: "https://foo.com",
NoProxy: "bar.com",
},
},
}
for _, c := range caseList {
t.Run(c.caseName, func(t *testing.T) {
pred := GetAddOnDeploymentPredicates()
createEvent := event.CreateEvent{
Object: defaultAddonDeploymentConfig,
}

if c.expectedCreate {
if !pred.CreateFunc(createEvent) {
t.Fatalf("pre func return false on applied createevent in case: (%v)", c.caseName)
}
}

newDefaultAddonDeploymentConfig := defaultAddonDeploymentConfig.DeepCopy()
newDefaultAddonDeploymentConfig.Spec.ProxyConfig.HTTPProxy = "http://bar1.com"
updateEvent := event.UpdateEvent{
ObjectOld: defaultAddonDeploymentConfig,
ObjectNew: newDefaultAddonDeploymentConfig,
}
if c.expectedUpdate {
if !pred.UpdateFunc(updateEvent) {
t.Fatalf("pre func return false on applied update event in case: (%v)", c.caseName)
}
}

deleteEvent := event.DeleteEvent{
Object: defaultAddonDeploymentConfig,
}
if c.expectedDelete {
if !pred.DeleteFunc(deleteEvent) {
t.Fatalf("pre func return false on applied delete event in case: (%v)", c.caseName)
}
}
})
}
}
1 change: 1 addition & 0 deletions operators/multiclusterobservability/pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ const (
MCHUpdatedRequestName = "mch-updated-request"
MCOUpdatedRequestName = "mco-updated-request"
ClusterManagementAddOnUpdateName = "clustermgmtaddon-updated-request"
AddonDeploymentConfigUpdateName = "addondc-updated-request"
MulticloudConsoleRouteName = "multicloud-console"
ImageManifestConfigMapNamePrefix = "mch-image-manifest-"
OCMManifestConfigMapTypeLabelKey = "ocm-configmap-type"
Expand Down

0 comments on commit 7fb7465

Please sign in to comment.