Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ocm: add WaitForAllPoliciesComplianceState function #906

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions pkg/ocm/policylist.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ package ocm
import (
"context"
"fmt"
"time"

"github.com/golang/glog"
"github.com/openshift-kni/eco-goinfra/pkg/clients"
"k8s.io/apimachinery/pkg/util/wait"
policiesv1 "open-cluster-management.io/governance-policy-propagator/api/v1"
runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
)
Expand Down Expand Up @@ -67,3 +69,62 @@ func ListPoliciesInAllNamespaces(apiClient *clients.Settings,

return policyObjects, nil
}

// WaitForAllPoliciesComplianceState wait up to timeout until all policies have complianceState. Policies are listed
// with options on every poll and then these policies have their compliance state checked.
func WaitForAllPoliciesComplianceState(
apiClient *clients.Settings,
complianceState policiesv1.ComplianceState,
timeout time.Duration,
options ...runtimeclient.ListOptions) error {
if apiClient == nil {
glog.V(100).Info("Policies 'apiClient' parameter cannot be nil")

return fmt.Errorf("failed to wait for policies compliance state, 'apiClient' parameter is nil")
}

err := apiClient.AttachScheme(policiesv1.AddToScheme)
if err != nil {
glog.V(100).Info("Failed to add Policy scheme to client schemes")

return err
}

logMessage := fmt.Sprintf("Waiting up to %s until policies have compliance state %s", timeout, complianceState)
passedOptions := runtimeclient.ListOptions{}

if len(options) > 1 {
glog.V(100).Infof("'options' parameter must be empty or single-valued")

return fmt.Errorf("error: more than one ListOptions was passed")
}

if len(options) == 1 {
passedOptions = options[0]
logMessage += fmt.Sprintf(", listing with the options %v", passedOptions)
}

glog.V(100).Info(logMessage)

return wait.PollUntilContextTimeout(
context.TODO(), time.Second, timeout, true, func(ctx context.Context) (bool, error) {
policies, err := ListPoliciesInAllNamespaces(apiClient, passedOptions)
if err != nil {
glog.V(100).Infof("Failed to list policies while waiting for compliance state: %v", err)

return false, nil
}

for _, policy := range policies {
policyComplianceState := policy.Definition.Status.ComplianceState
if policyComplianceState != complianceState {
glog.V(100).Infof("Policy %s in namespace %s has compliance state %s, not %s",
policy.Definition.Name, policy.Definition.Namespace, policyComplianceState, complianceState)

return false, nil
}
}

return true, nil
})
}
61 changes: 61 additions & 0 deletions pkg/ocm/policylist_test.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package ocm

import (
"context"
"fmt"
"testing"
"time"

"github.com/openshift-kni/eco-goinfra/pkg/clients"
"github.com/stretchr/testify/assert"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
policiesv1 "open-cluster-management.io/governance-policy-propagator/api/v1"
runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
)

Expand Down Expand Up @@ -69,3 +73,60 @@ func TestListPoliciesInAllNamespaces(t *testing.T) {
}
}
}

func TestWaitForAllPoliciesComplianceState(t *testing.T) {
testCases := []struct {
compliant bool
client bool
listOptions []runtimeclient.ListOptions
expectedError error
}{
{
compliant: true,
client: true,
listOptions: nil,
expectedError: nil,
},
{
compliant: false,
client: true,
listOptions: nil,
expectedError: context.DeadlineExceeded,
},
{
compliant: true,
client: false,
listOptions: nil,
expectedError: fmt.Errorf("failed to wait for policies compliance state, 'apiClient' parameter is nil"),
},
{
compliant: true,
client: true,
listOptions: []runtimeclient.ListOptions{
{LabelSelector: labels.NewSelector()},
{LabelSelector: labels.NewSelector()},
},
expectedError: fmt.Errorf("error: more than one ListOptions was passed"),
},
}

for _, testCase := range testCases {
var testSettings *clients.Settings

if testCase.client {
policy := buildDummyPolicy(defaultPolicyName, defaultPolicyNsName)

if testCase.compliant {
policy.Status.ComplianceState = policiesv1.Compliant
}

testSettings = clients.GetTestClients(clients.TestClientParams{
K8sMockObjects: []runtime.Object{policy},
SchemeAttachers: policyTestSchemes,
})
}

err := WaitForAllPoliciesComplianceState(testSettings, policiesv1.Compliant, time.Second, testCase.listOptions...)
assert.Equal(t, testCase.expectedError, err)
}
}
Loading