Skip to content

Commit

Permalink
Automated cherry pick of #2713 origin release v1.30 (#2717)
Browse files Browse the repository at this point in the history
* Postpone policy recommendation scope watches until apiserver is up and running

* Block the policy recommendation controller if the apiserver watch is not established yet

* Mark readyFlag in unit tests.
  • Loading branch information
rene-dekker authored Jul 7, 2023
1 parent 4816f41 commit 347ed9b
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,9 @@ func Add(mgr manager.Manager, opts options.AddOptions) error {
}
licenseAPIReady := &utils.ReadyFlag{}
tierWatchReady := &utils.ReadyFlag{}
policyRecScopeWatchReady := &utils.ReadyFlag{}

reconciler := newReconciler(mgr, opts, licenseAPIReady, tierWatchReady)
reconciler := newReconciler(mgr, opts, licenseAPIReady, tierWatchReady, policyRecScopeWatchReady)

policyRecController, err := controller.New(PolicyRecommendationControllerName, mgr,
controller.Options{
Expand All @@ -83,6 +84,7 @@ func Add(mgr manager.Manager, opts options.AddOptions) error {
}

go utils.WaitToAddLicenseKeyWatch(policyRecController, k8sClient, log, licenseAPIReady)
go utils.WaitToAddPolicyRecommendationScopeWatch(policyRecController, k8sClient, log, policyRecScopeWatchReady)
go utils.WaitToAddTierWatch(networkpolicy.TigeraComponentTierName, policyRecController, k8sClient, log, tierWatchReady)
go utils.WaitToAddNetworkPolicyWatches(policyRecController, k8sClient, log, []types.NamespacedName{
{Name: render.PolicyRecommendationPolicyName, Namespace: render.PolicyRecommendationNamespace},
Expand All @@ -98,17 +100,19 @@ func newReconciler(
opts options.AddOptions,
licenseAPIReady *utils.ReadyFlag,
tierWatchReady *utils.ReadyFlag,
policyRecScopeWatchReady *utils.ReadyFlag,
) reconcile.Reconciler {

r := &ReconcilePolicyRecommendation{
client: mgr.GetClient(),
scheme: mgr.GetScheme(),
provider: opts.DetectedProvider,
status: status.New(mgr.GetClient(), "policy-recommendation", opts.KubernetesVersion),
clusterDomain: opts.ClusterDomain,
licenseAPIReady: licenseAPIReady,
tierWatchReady: tierWatchReady,
usePSP: opts.UsePSP,
client: mgr.GetClient(),
scheme: mgr.GetScheme(),
provider: opts.DetectedProvider,
status: status.New(mgr.GetClient(), "policy-recommendation", opts.KubernetesVersion),
clusterDomain: opts.ClusterDomain,
licenseAPIReady: licenseAPIReady,
tierWatchReady: tierWatchReady,
policyRecScopeWatchReady: policyRecScopeWatchReady,
usePSP: opts.UsePSP,
}

r.status.Run(opts.ShutdownContext)
Expand All @@ -126,12 +130,6 @@ func add(c controller.Controller) error {
return err
}

// Watch for changes to primary resource PolicyRecommendationScope
err = c.Watch(&source.Kind{Type: &v3.PolicyRecommendationScope{}}, &handler.EnqueueRequestForObject{})
if err != nil {
return fmt.Errorf("policy-recommendation-controller failed to watch policy recommendation scope resource: %w", err)
}

if err = utils.AddNetworkWatch(c); err != nil {
return fmt.Errorf("policy-recommendation-controller failed to watch Network resource: %w", err)
}
Expand Down Expand Up @@ -190,14 +188,15 @@ var _ reconcile.Reconciler = &ReconcilePolicyRecommendation{}
type ReconcilePolicyRecommendation struct {
// This client, initialized using mgr.Client() above, is a split client
// that reads objects from the cache and writes to the apiserver
client client.Client
clusterDomain string
licenseAPIReady *utils.ReadyFlag
scheme *runtime.Scheme
status status.StatusManager
tierWatchReady *utils.ReadyFlag
provider operatorv1.Provider
usePSP bool
client client.Client
clusterDomain string
licenseAPIReady *utils.ReadyFlag
scheme *runtime.Scheme
status status.StatusManager
tierWatchReady *utils.ReadyFlag
policyRecScopeWatchReady *utils.ReadyFlag
provider operatorv1.Provider
usePSP bool
}

func GetPolicyRecommendation(ctx context.Context, cli client.Client) (*operatorv1.PolicyRecommendation, error) {
Expand Down Expand Up @@ -251,6 +250,12 @@ func (r *ReconcilePolicyRecommendation) Reconcile(ctx context.Context, request r
return reconcile.Result{RequeueAfter: 10 * time.Second}, nil
}

// Validate that the policy recommendation scope watch is ready before querying the tier to ensure we utilize the cache.
if !r.policyRecScopeWatchReady.IsReady() {
r.status.SetDegraded(operatorv1.ResourceNotReady, "Waiting for PolicyRecommendationScope watch to be established", err, reqLogger)
return reconcile.Result{RequeueAfter: 10 * time.Second}, nil
}

// Ensure the allow-tigera tier exists, before rendering any network policies within it.
if err := r.client.Get(ctx, client.ObjectKey{Name: networkpolicy.TigeraComponentTierName}, &v3.Tier{}); err != nil {
if errors.IsNotFound(err) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,13 @@ var _ = Describe("PolicyRecommendation controller tests", func() {
// Create an object we can use throughout the test to do the compliance reconcile loops.
// As the parameters in the client changes, we expect the outcomes of the reconcile loops to change.
r = ReconcilePolicyRecommendation{
client: c,
scheme: scheme,
provider: operatorv1.ProviderNone,
status: mockStatus,
licenseAPIReady: &utils.ReadyFlag{},
tierWatchReady: &utils.ReadyFlag{},
client: c,
scheme: scheme,
provider: operatorv1.ProviderNone,
status: mockStatus,
licenseAPIReady: &utils.ReadyFlag{},
tierWatchReady: &utils.ReadyFlag{},
policyRecScopeWatchReady: &utils.ReadyFlag{},
}

// We start off with a 'standard' installation, with nothing special
Expand Down Expand Up @@ -163,6 +164,7 @@ var _ = Describe("PolicyRecommendation controller tests", func() {
// mark that the watches were successful
r.licenseAPIReady.MarkAsReady()
r.tierWatchReady.MarkAsReady()
r.policyRecScopeWatchReady.MarkAsReady()
})

Context("image reconciliation", func() {
Expand Down Expand Up @@ -229,12 +231,13 @@ var _ = Describe("PolicyRecommendation controller tests", func() {
readyFlag = &utils.ReadyFlag{}
readyFlag.MarkAsReady()
r = ReconcilePolicyRecommendation{
client: c,
scheme: scheme,
provider: operatorv1.ProviderNone,
status: mockStatus,
licenseAPIReady: readyFlag,
tierWatchReady: readyFlag,
client: c,
scheme: scheme,
provider: operatorv1.ProviderNone,
status: mockStatus,
licenseAPIReady: readyFlag,
tierWatchReady: readyFlag,
policyRecScopeWatchReady: readyFlag,
}
})

Expand Down
4 changes: 4 additions & 0 deletions pkg/controller/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,10 @@ func WaitToAddLicenseKeyWatch(controller controller.Controller, c kubernetes.Int
WaitToAddResourceWatch(controller, c, log, flag, []client.Object{&v3.LicenseKey{TypeMeta: metav1.TypeMeta{Kind: v3.KindLicenseKey}}})
}

func WaitToAddPolicyRecommendationScopeWatch(controller controller.Controller, c kubernetes.Interface, log logr.Logger, flag *ReadyFlag) {
WaitToAddResourceWatch(controller, c, log, flag, []client.Object{&v3.PolicyRecommendationScope{TypeMeta: metav1.TypeMeta{Kind: v3.KindPolicyRecommendationScope}}})
}

func WaitToAddNetworkPolicyWatches(controller controller.Controller, c kubernetes.Interface, log logr.Logger, policies []types.NamespacedName) {
objs := []client.Object{}
for _, policy := range policies {
Expand Down

0 comments on commit 347ed9b

Please sign in to comment.