diff --git a/bundle/manifests/fence-agents-remediation.clusterserviceversion.yaml b/bundle/manifests/fence-agents-remediation.clusterserviceversion.yaml index 1a573ea3..810ed95a 100644 --- a/bundle/manifests/fence-agents-remediation.clusterserviceversion.yaml +++ b/bundle/manifests/fence-agents-remediation.clusterserviceversion.yaml @@ -221,6 +221,11 @@ spec: - --leader-elect command: - /manager + env: + - name: DEPLOYMENT_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace image: quay.io/medik8s/fence-agents-remediation-operator:latest livenessProbe: httpGet: diff --git a/config/manager/manager.yaml b/config/manager/manager.yaml index cf11cecc..b87a5a1b 100644 --- a/config/manager/manager.yaml +++ b/config/manager/manager.yaml @@ -33,6 +33,11 @@ spec: - --leader-elect image: controller:latest name: manager + env: + - name: DEPLOYMENT_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace securityContext: allowPrivilegeEscalation: false livenessProbe: diff --git a/controllers/fenceagentsremediation_controller.go b/controllers/fenceagentsremediation_controller.go index a1de2d5e..c49f5ed0 100644 --- a/controllers/fenceagentsremediation_controller.go +++ b/controllers/fenceagentsremediation_controller.go @@ -20,23 +20,17 @@ import ( "context" "errors" "fmt" - "net/http" "github.com/go-logr/logr" - corev1 "k8s.io/api/core/v1" apiErrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" "github.com/medik8s/fence-agents-remediation/api/v1alpha1" "github.com/medik8s/fence-agents-remediation/pkg/cli" -) - -var ( - faPodLabels = map[string]string{"app": "fence-agents-remediation-operator"} + "github.com/medik8s/fence-agents-remediation/pkg/utils" ) // FenceAgentsRemediationReconciler reconciles a FenceAgentsRemediation object @@ -88,7 +82,7 @@ func (r *FenceAgentsRemediationReconciler) Reconcile(ctx context.Context, req ct // TODO: Validate FAR CR name to nodeName. Run isNodeNameValid // Fetch the FAR's pod r.Log.Info("Fetch FAR's pod") - pod, err := r.getFenceAgentsPod(req.Namespace) + pod, err := utils.GetFenceAgentsRemediationPod(req.Name, r.Client) if err != nil { return emptyResult, err } @@ -109,33 +103,6 @@ func (r *FenceAgentsRemediationReconciler) Reconcile(ctx context.Context, req ct return emptyResult, nil } -// getFenceAgentsPod fetches the FAR pod based on FAR's label and namespace -func (r *FenceAgentsRemediationReconciler) getFenceAgentsPod(namespace string) (*corev1.Pod, error) { - - pods := new(corev1.PodList) - - podLabelsSelector, _ := metav1.LabelSelectorAsSelector( - &metav1.LabelSelector{MatchLabels: faPodLabels}) - options := client.ListOptions{ - LabelSelector: podLabelsSelector, - Namespace: namespace, - } - if err := r.Client.List(context.Background(), pods, &options); err != nil { - r.Log.Error(err, "failed fetching Fence Agent layer pod") - return nil, err - } - if len(pods.Items) == 0 { - r.Log.Info("No Fence Agent pods were found") - podNotFoundErr := &apiErrors.StatusError{ErrStatus: metav1.Status{ - Status: metav1.StatusFailure, - Code: http.StatusNotFound, - Reason: metav1.StatusReasonNotFound, - }} - return nil, podNotFoundErr - } - return &pods.Items[0], nil -} - // buildFenceAgentParams collects the FAR's parameters for the node based on FAR CR func buildFenceAgentParams(far *v1alpha1.FenceAgentsRemediation) ([]string, error) { var fenceAgentParams []string diff --git a/controllers/fenceagentsremediation_controller_test.go b/controllers/fenceagentsremediation_controller_test.go index 0354c98e..73fb1ce2 100644 --- a/controllers/fenceagentsremediation_controller_test.go +++ b/controllers/fenceagentsremediation_controller_test.go @@ -41,6 +41,11 @@ const ( fenceAgentIPMI = "fence_ipmilan" ) +var ( + faPodLabels = map[string]string{"app": "fence-agents-remediation-operator"} + fenceAgentsPod *corev1.Pod +) + var _ = Describe("FAR Controller", func() { var ( underTestFAR *v1alpha1.FenceAgentsRemediation @@ -64,7 +69,6 @@ var _ = Describe("FAR Controller", func() { }, } underTestFAR = newFenceAgentsRemediation(validNodeName, fenceAgentIPMI, testShareParam, testNodeParam) - fenceAgentsPod := buildFarPod() Context("Functionality", func() { Context("buildFenceAgentParams", func() { @@ -87,11 +91,11 @@ var _ = Describe("FAR Controller", func() { }) }) }) - Context("Reconcile", func() { //Scenarios BeforeEach(func() { + fenceAgentsPod = buildFarPod() // Create fenceAgentsPod and FAR Expect(k8sClient.Create(context.Background(), fenceAgentsPod)).NotTo(HaveOccurred()) Expect(k8sClient.Create(context.Background(), underTestFAR)).NotTo(HaveOccurred()) diff --git a/pkg/utils/namespaces.go b/pkg/utils/namespaces.go new file mode 100644 index 00000000..1cde4ad1 --- /dev/null +++ b/pkg/utils/namespaces.go @@ -0,0 +1,21 @@ +package utils + +import ( + "fmt" + "os" +) + +// deployNamespaceEnv is a constant for env variable DEPLOYMENT_NAMESPACE +// which specifies the Namespace that the operator's deployment was installed/run. +// It has been set using Downward API (https://kubernetes.io/docs/concepts/workloads/pods/downward-api/) in manager.yaml +const deployNamespaceEnv = "DEPLOYMENT_NAMESPACE" + +// GetDeploymentNamespace returns the Namespace this operator is deployed/installed on. +func GetDeploymentNamespace() (string, error) { + + ns, found := os.LookupEnv(deployNamespaceEnv) + if !found { + return "", fmt.Errorf("%s must be set", deployNamespaceEnv) + } + return ns, nil +} diff --git a/pkg/utils/pods.go b/pkg/utils/pods.go new file mode 100644 index 00000000..8de8b219 --- /dev/null +++ b/pkg/utils/pods.go @@ -0,0 +1,41 @@ +package utils + +import ( + "context" + "fmt" + "net/http" + + corev1 "k8s.io/api/core/v1" + apiErrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/selection" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +// GetFenceAgentsRemediationPod fetches the FAR pod based on FAR's label and namespace +func GetFenceAgentsRemediationPod(nodeName string, r client.Reader) (*corev1.Pod, error) { + pods := &corev1.PodList{} + + selector := labels.NewSelector() + requirement, _ := labels.NewRequirement("app", selection.Equals, []string{"fence-agents-remediation-operator"}) + selector = selector.Add(*requirement) + podNamespace, _ := GetDeploymentNamespace() + + err := r.List(context.Background(), pods, &client.ListOptions{LabelSelector: selector, Namespace: podNamespace}) + if err != nil { + fmt.Printf("failed fetching FAR pod") + return nil, err + } + if len(pods.Items) == 0 { + fmt.Printf("No Fence Agent pods were found") + podNotFoundErr := &apiErrors.StatusError{ErrStatus: metav1.Status{ + Status: metav1.StatusFailure, + Code: http.StatusNotFound, + Reason: metav1.StatusReasonNotFound, + }} + return nil, podNotFoundErr + } + + return &pods.Items[0], nil +}