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

CFE-866: Add secret manager for routes to consume secret_monitor #1626

Merged

Conversation

chiragkyal
Copy link
Member

@chiragkyal chiragkyal commented Nov 22, 2023

Description

This PR adds route layer (introduces a new secretmanager package) on top of #1675 to consume the secret_monitor.
These changes primarily focus on enhancing the functionality of managing secrets associated with routes.

Important Functions:

  • RegisterRoute: Allows registering a route with a secret, enabling dynamic monitoring of secret changes associated with the route.
  • UnregisterRoute: Provides functionality to remove the registration of a route from the monitor.
  • GetSecret: Enables retrieving the secret object registered with a route.

Related: CFE-866
Implements: openshift/enhancements#1307

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Nov 22, 2023
@openshift-ci openshift-ci bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Nov 22, 2023
@openshift-ci-robot
Copy link

openshift-ci-robot commented Nov 22, 2023

@chiragkyal: This pull request references CFE-866 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.15.0" version, but no target version was set.

In response to this:

Related: CFE-866
Implements: openshift/enhancements#1307

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

Copy link
Contributor

openshift-ci bot commented Nov 22, 2023

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@chiragkyal
Copy link
Member Author

Continued from #1518

@chiragkyal
Copy link
Member Author

/retest

@chiragkyal chiragkyal force-pushed the feature/secret-manager branch 2 times, most recently from 2f5683e to 632b0c8 Compare January 18, 2024 10:18
@chiragkyal chiragkyal changed the title [WIP] CFE-866: Add secret monitor for Routes CFE-866: Add secret monitor for Routes Jan 18, 2024
@chiragkyal chiragkyal marked this pull request as ready for review January 18, 2024 10:18
@openshift-ci openshift-ci bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jan 18, 2024
Copy link
Contributor

@deads2k deads2k left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

solid start

pkg/route/secret/manager.go Outdated Show resolved Hide resolved
pkg/route/secret/monitor.go Outdated Show resolved Hide resolved
pkg/route/secret/manager.go Outdated Show resolved Hide resolved
pkg/route/secret/secret_monitor.go Outdated Show resolved Hide resolved
pkg/route/secret/secret_monitor.go Outdated Show resolved Hide resolved
pkg/route/secret/secret_monitor.go Outdated Show resolved Hide resolved
pkg/route/secret/secret_monitor.go Outdated Show resolved Hide resolved
pkg/route/secret/secret_monitor.go Outdated Show resolved Hide resolved
pkg/route/secret/manager.go Outdated Show resolved Hide resolved
pkg/route/secret/monitor.go Outdated Show resolved Hide resolved
@candita
Copy link
Contributor

candita commented Jan 31, 2024

/assign @alebedev87

pkg/route/secret/monitor.go Outdated Show resolved Hide resolved
pkg/route/secret/monitor.go Outdated Show resolved Hide resolved
// each route (namespace/routeName) should be registered only once with any secret.
// Note: inside a namespace multiple different routes can be registered(watch) with a common secret
key := generateKey(namespace, routeName)
if _, exists := m.registeredHandlers[key]; exists {
Copy link
Contributor

@deads2k deads2k Feb 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the secret name changes, what should happen? Probably a remove and then an add?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct, unregister old secret and register new secret.

return apierrors.NewInternalError(fmt.Errorf("route already registered with key %s", key))
}

handlerRegistration, err := m.monitor.AddSecretEventHandler(namespace, secretName, m.secretHandler)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably worth considering how your consuming layers will expect the "route changed secret" to be represented to them.

}

// wait for informer store sync, to load secret
if err := wait.PollImmediate(10*time.Millisecond, time.Second, func() (done bool, err error) { return handlerRegistration.HasSynced(), nil }); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because you waited for the HasSync in the step above, this wait should no longer be necessary, right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That HasSync will be called only once after starting the informer. Correct me if I'm wrong, but I think we need to call HasSync for every GetSecret invocation to update the cache with the latest state of the resource.

@chiragkyal
Copy link
Member Author

/test all

@chiragkyal
Copy link
Member Author

As discussed, we'll split this PR into 2 PRs.
I've raised #1675 which will have only secret monitoring logic and this PR will be updated to consume that for routes.

pkg/route/secretmanager/manager_test.go Outdated Show resolved Hide resolved
pkg/route/secret/monitor.go Outdated Show resolved Hide resolved
Copy link

@alebedev87 alebedev87 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Second iteration, mostly the nit picks.

pkg/route/secretmanager/manager_test.go Outdated Show resolved Hide resolved
pkg/route/secret/monitor_test.go Outdated Show resolved Hide resolved
pkg/route/secret/monitor_test.go Outdated Show resolved Hide resolved
pkg/route/secret/monitor_test.go Outdated Show resolved Hide resolved
pkg/route/secret/monitor_test.go Outdated Show resolved Hide resolved
pkg/route/secret/secret_monitor_test.go Outdated Show resolved Hide resolved
pkg/route/secret/secret_monitor_test.go Outdated Show resolved Hide resolved
pkg/route/secret/secret_monitor_test.go Outdated Show resolved Hide resolved
pkg/route/secret/secret_monitor_test.go Outdated Show resolved Hide resolved
Comment on lines 207 to 209
if err != nil {
return nil, err
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the error is checked after the exist variable?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Informer's cache (GetByKey()) is returning error even with exists , so we should handle error instead of ignoring it.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I didn't make the question clear. I meant that why not checking the error before we check exist. It may be misleading as exist may be false just because it's a default value returned in case of an error. This may result in a wrong error returned from the function.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, that makes sense. Moved err check before exist. Thanks!

@chiragkyal
Copy link
Member Author

/hold
For #1675
We want to keep the secretmanager and monitor in two separate PRs.

@openshift-ci openshift-ci bot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Apr 19, 2024
@alebedev87
Copy link

/lgtm

@openshift-ci openshift-ci bot added the lgtm Indicates that a PR is ready to be merged. label Apr 19, 2024
Copy link
Contributor

@Miciah Miciah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great. All my comments are suggestions to fix typos in comments or log or error messages and a few minor questions around error values and test code. Feel free to take or leave my suggestions, or handle them in a follow-up.
/lgtm

return i.informer.HasSynced()
}

// StartInformer starts and runs the informer util the provided context is canceled,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// StartInformer starts and runs the informer util the provided context is canceled,
// StartInformer starts and runs the informer until the provided context is canceled,

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

defer i.lock.Unlock()

if i.stopped {
return nil, fmt.Errorf("can not add handler %v to already stopped informer", handler)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return nil, fmt.Errorf("can not add handler %v to already stopped informer", handler)
return nil, fmt.Errorf("cannot add handler %v to already stopped informer", handler)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated

// secret identifier (namespace/secret)
key := NewObjectKey(namespace, secretName)

// start secret informer if monitor does not exists
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// start secret informer if monitor does not exists
// Start secret informer if monitor does not exist.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

return nil, fmt.Errorf("failed waiting for cache sync")
}

// add item key to monitors map // add watch to the list
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The // add watch to the list looks conspicuous—is this a stale comment that accidentally got joined with the // add item key to monitors map comment?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it was a stale comment. I've removed // add watch to the list comment

// add item key to monitors map // add watch to the list
s.monitors[key] = m

klog.Info("secret informer started", " item key ", key)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here and below, are the extra spaces intended to be there?

Suggested change
klog.Info("secret informer started", " item key ", key)
klog.Info("secret informer started", "item key", key)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, these are intended because it looks like klog.Info is not putting spaces between two comma , separated strings.

Copy link
Contributor

@Miciah Miciah Apr 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I was thinking these were key-value pairs, like go-logr/logr uses. Why not use a format?

Suggested change
klog.Info("secret informer started", " item key ", key)
klog.Infof("secret informer started for item with key %v", key)

This is a minor issue and can be addressed in a follow-up if you decide to take my suggestion.

Comment on lines 290 to 295
// for handling nil pointer dereference
defer func() {
if err := recover(); err != nil && !s.expectErr {
t.Errorf("unexpected error %v", err)
}
}()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This recover block highlights an oddity of this test: The "nil handler is provided" test case isn't actually testing the behavior of AddEventHandler; it's testing the behavior of the Go runtime, to verify that dereferencing a nil pointer causes a panic—right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was there to recover from panic when handle.GetHandler() is executed inside RemoveEventHandler, given a nil SecretEventHandlerRegistration.

I think a much easier way would be to add if statement inside RemoveEventHandler to check nil SecretEventHandlerRegistration.

I've added the following the latest commit

if handle == nil {
    return fmt.Errorf("nil handler registration is provided")
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like it—the test is simpler, and the method is more robust. Thanks!

Comment on lines 182 to 185
// Delete keys if already removed
for _, keyRemoved := range s.alreadyRemoved {
delete(sm.monitors, keyRemoved)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this testing something that is expected to happen, or is this testing that RemoveSecretEventHandler behaves correctly if the secret monitor's internal data structures are inexplicably corrupted?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this testing that RemoveSecretEventHandler behaves correctly if the secret monitor's internal data structures are inexplicably corrupted?

For this reason(^)

It is trying to simulate the condition when the secret monitor does not contain the intended key. This is unlikely to happen, but I think we should have a test to check RemoveSecretEventHandler catches this issue.

m, exists := s.monitors[key]
if !exists {
return fmt.Errorf("secret monitor already removed for item key %v", key)
}


gotSec, gotErr := sm.GetSecret(context.TODO(), h)
if (gotErr != nil) != s.expectErr {
t.Fatalf("expected errors to be %t, but got %t", s.expectErr, err != nil)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
t.Fatalf("expected errors to be %t, but got %t", s.expectErr, err != nil)
t.Fatalf("expected errors to be %t, but got %t", s.expectErr, gotErr != nil)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

Comment on lines 69 to 76
return apierrors.NewInternalError(fmt.Errorf("route already registered with key %s", key))
}

// Add a secret event handler for the specified namespace and secret, with the handler functions.
klog.V(5).Infof("trying to add handler for key %s with secret %s", key, secretName)
handlerRegistration, err := m.monitor.AddSecretEventHandler(ctx, namespace, secretName, handler)
if err != nil {
return apierrors.NewInternalError(err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason to use apierrors.NewInternalError here? I thought apierrors.NewInternalError was intended for errors that originated from the API server. And even if it's safe to use outside of the API server context, it isn't clear to me why the error needs to be wrapped.

That said, I don't see any router code that uses apierrors.IsInternalError to do something special with such errors, so using apierrors.NewInternalError shouldn't cause any problems for now.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I also think router code will not make use of this wrapped error by calling apierrors.IsInternalError. So, to keep it consistent, I've drooped the apierrors usage from this package.

return nil, apierrors.NewInternalError(fmt.Errorf("no handler registered with key %s", key))
}

// get secret from secrt monitor's cache using registered handler
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// get secret from secrt monitor's cache using registered handler
// Get the secret from the secret monitor's cache using the registered handler.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

@openshift-ci openshift-ci bot removed the lgtm Indicates that a PR is ready to be merged. label Apr 22, 2024
@chiragkyal
Copy link
Member Author

Thanks @Miciah for the review comments, I've addressed them. PTAL. If there isn't any new suggestions, would appreciated your lgtm in #1675.
I've cherry-picked the secret monitor related changes (which addressed your comments) into #1675.

@Miciah
Copy link
Contributor

Miciah commented Apr 22, 2024

Thanks!
/lgtm

@openshift-ci openshift-ci bot added the lgtm Indicates that a PR is ready to be merged. label Apr 22, 2024
Signed-off-by: chiragkyal <ckyal@redhat.com>
@openshift-ci openshift-ci bot added approved Indicates a PR has been approved by an approver from all required OWNERS files. and removed lgtm Indicates that a PR is ready to be merged. labels Apr 25, 2024
@openshift-ci-robot
Copy link

openshift-ci-robot commented Apr 25, 2024

@chiragkyal: This pull request references CFE-866 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.16.0" version, but no target version was set.

In response to this:

This PR adds route layer (secretmanager) on top of #1675 to consume the secret_monitor.

Related: CFE-866
Implements: openshift/enhancements#1307

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@chiragkyal chiragkyal changed the title CFE-866: Add secret monitor for Routes CFE-866: Add secret manager for routes to consume secret_monitor Apr 25, 2024
@chiragkyal
Copy link
Member Author

/unhold
#1675 is merged. Rebased to master.

@openshift-ci openshift-ci bot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Apr 25, 2024
Copy link
Contributor

openshift-ci bot commented Apr 25, 2024

@chiragkyal: all tests passed!

Full PR test history. Your PR dashboard.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here.

@openshift-ci-robot
Copy link

openshift-ci-robot commented Apr 25, 2024

@chiragkyal: This pull request references CFE-866 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.16.0" version, but no target version was set.

In response to this:

Description

This PR adds route layer (introduces a new secretmanager package) on top of #1675 to consume the secret_monitor.
These changes primarily focus on enhancing the functionality of managing secrets associated with routes.

Important Functions:

  • RegisterRoute: Allows registering a route with a secret, enabling dynamic monitoring of secret changes associated with the route.
  • UnregisterRoute: Provides functionality to remove the registration of a route from the monitor.
  • GetSecret: Enables retrieving the secret object registered with a route.

Related: CFE-866
Implements: openshift/enhancements#1307

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@Miciah
Copy link
Contributor

Miciah commented Apr 25, 2024

/lgtm

@openshift-ci openshift-ci bot added the lgtm Indicates that a PR is ready to be merged. label Apr 25, 2024
Copy link
Contributor

openshift-ci bot commented Apr 25, 2024

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: alebedev87, chiragkyal, Miciah

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-merge-bot openshift-merge-bot bot merged commit f9d4805 into openshift:master Apr 25, 2024
4 checks passed
@chiragkyal chiragkyal deleted the feature/secret-manager branch April 25, 2024 16:14
chiragkyal added a commit to chiragkyal/openshift-router that referenced this pull request May 14, 2024
Vendoring openshift/library-go#1626

Signed-off-by: chiragkyal <ckyal@redhat.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. lgtm Indicates that a PR is ready to be merged.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants