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

feat: Add reconcile controller logic issue #37 #39

Merged
merged 9 commits into from
Oct 7, 2022
Merged

Conversation

hessjcg
Copy link
Collaborator

@hessjcg hessjcg commented Oct 4, 2022

Adds the logic to reconcile changes to AuthProxyWorkload resources to workloads.

@hessjcg hessjcg requested a review from a team October 4, 2022 02:44
controllers/authproxyworkload_controller.go Outdated Show resolved Hide resolved
controllers/authproxyworkload_controller.go Show resolved Hide resolved
controllers/authproxyworkload_controller.go Show resolved Hide resolved
controllers/authproxyworkload_controller.go Outdated Show resolved Hide resolved
controllers/authproxyworkload_controller.go Outdated Show resolved Hide resolved
test/helpers/testcases.go Outdated Show resolved Hide resolved
test/helpers/testcases.go Outdated Show resolved Hide resolved
test/integration/integration_test.go Outdated Show resolved Hide resolved
test/integration/integration_test.go Outdated Show resolved Hide resolved
controllers/authproxyworkload_controller.go Show resolved Hide resolved
@enocom enocom requested a review from a team October 4, 2022 22:08
Copy link
Collaborator Author

@hessjcg hessjcg left a comment

Choose a reason for hiding this comment

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

Updates from this review have been pushed.

controllers/authproxyworkload_controller.go Outdated Show resolved Hide resolved
controllers/authproxyworkload_controller.go Outdated Show resolved Hide resolved
controllers/authproxyworkload_controller.go Outdated Show resolved Hide resolved
controllers/authproxyworkload_controller.go Show resolved Hide resolved
controllers/authproxyworkload_controller.go Show resolved Hide resolved
controllers/list_workloads.go Outdated Show resolved Hide resolved
test/helpers/testcases.go Outdated Show resolved Hide resolved
test/integration/integration_test.go Outdated Show resolved Hide resolved
test/integration/integration_test.go Outdated Show resolved Hide resolved
test/helpers/testcases.go Outdated Show resolved Hide resolved
@hessjcg hessjcg requested review from enocom and shubha-rajan October 6, 2022 00:50
@hessjcg hessjcg assigned hessjcg and unassigned enocom and shubha-rajan Oct 6, 2022
Copy link
Collaborator Author

@hessjcg hessjcg left a comment

Choose a reason for hiding this comment

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

Resolved the comments I just fixed as @enocom intended.

controllers/authproxyworkload_controller.go Outdated Show resolved Hide resolved
func (c *recentlyDeletedCache) get(k types.NamespacedName) bool {
c.lock.RLock()
defer c.lock.RUnlock()
if c.values == nil {
Copy link
Member

Choose a reason for hiding this comment

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

Reading out of a nil map is totally fine. It's setting into a nil map that will panic.

So this could just be:

deleted, ok := c.values[k]
if !ok {
  return false
}
return deleted

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

fixed.

// AuthProxyWorkloadReconciler reconciles a AuthProxyWorkload object
type AuthProxyWorkloadReconciler struct {
client.Client
Scheme *runtime.Scheme
Scheme *runtime.Scheme
recentlyDeleted recentlyDeletedCache
Copy link
Member

Choose a reason for hiding this comment

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

Since you're defining methods on recentlyDeletedCache as pointer receivers, this should match and be a pointer, if only to avoid the ambiguity of whether your sync.Mutex gets copied (It doesn't, but still it's not immediately obvious).

Copy link
Member

Choose a reason for hiding this comment

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

It's probably worth adding an initializer so callers don't have to understand these details:

r := controllers.NewAuthProxyReconciler(mgr)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed.

func replaceCondition(conds []*metav1.Condition, newC *metav1.Condition) []*metav1.Condition {
for i := range conds {
c := conds[i]
if c.Type == newC.Type {
Copy link
Member

@enocom enocom Oct 7, 2022

Choose a reason for hiding this comment

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

nit: indent the error case

if c.Type !== newC.Type {
  continue
}
// .. happy path here

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed.

}

func TestReconcileDeleted(t *testing.T) {
wantRequeue := false
Copy link
Member

Choose a reason for hiding this comment

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

var wantRequeue bool

Copy link
Member

Choose a reason for hiding this comment

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

Also, let's move this closer to where it's used -- which might remove the need to even declare it as a variable.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I've inlined all of these test case parameters in this and other methods.

c := cb.WithObjects(p).Build()
r, req, ctx := reconciler(p, c)

c.Delete(ctx, p)
Copy link
Member

Choose a reason for hiding this comment

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

Let's check the error here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

fixed.

}

func TestReconcileState21ByName(t *testing.T) {
wantRequeue := false
Copy link
Member

Choose a reason for hiding this comment

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

Let's move these right above where they're used.

Copy link
Member

Choose a reason for hiding this comment

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

Ditto below. Keeping the declaration right next to the usage helps readability.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

All these are parameters to the assertion. I've embedded them below.

os.Exit(result)
}

func TestReconcileState11(t *testing.T) {
Copy link
Member

Choose a reason for hiding this comment

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

Many of the tests below look very similar. Could we refactor them into table based tests where we consolidate only what's different into test cases?

test/integration/integration_test.go Show resolved Hide resolved
@@ -194,5 +202,6 @@ func TestModifiesExistingDeployment(t *testing.T) {
ConnectionString: "region:project:inst",
ProxyImageURL: "proxy-image:latest",
}
helpers.TestModifiesExistingDeployment(tctx, true)
testRemove := helpers.TestModifiesExistingDeployment(tctx)
testRemove()
Copy link
Member

Choose a reason for hiding this comment

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

Should this be deferred?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

No, its actually a part of the testcase.

Copy link
Member

Choose a reason for hiding this comment

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

So testRemove should only run if the test before it didn't fail?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The TestModifiesExistingDeployment tescase does these steps:

  1. create a Deployment
  2. create an AuthProxyWorkload
  3. check that the Deployment was updated to have the proxy sidecar container
    (and optionally)
  4. delete the AuthProxyWorkload
  5. check that the Deployment is updated to not have the proxy sidecar container

I want to do steps 4 and 5 in the integration test, but skip tests 4 and 5 in the E2E test because after the test is over, I usually go inspect the state of the k8s cluster to see if the proxy sidecars are working right.

Originally the test helper was helpers.TestModifiesExistingDeployment(tctx, true) which would run the deployment, but you suggested that it should return a "cleanup function" instead. However, it's not really a cleanup function, It is extra steps in the test case.

I'm not totally convinced this was the right thing to do. Now that it returns a function that will do the last 2 steps of the test, it's more confusing.

Copy link
Member

Choose a reason for hiding this comment

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

I see that this helper is only used in one place. Maybe we shouldn't have a helper until we use it in a few places? Perhaps that's the problem -- we're not ready to make a shareable test helper function?

Copy link
Collaborator Author

@hessjcg hessjcg left a comment

Choose a reason for hiding this comment

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

I fixed the comments.

}

func TestReconcileDeleted(t *testing.T) {
wantRequeue := false
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I've inlined all of these test case parameters in this and other methods.

}

func TestReconcileState21ByName(t *testing.T) {
wantRequeue := false
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

All these are parameters to the assertion. I've embedded them below.

func (c *recentlyDeletedCache) get(k types.NamespacedName) bool {
c.lock.RLock()
defer c.lock.RUnlock()
if c.values == nil {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

fixed.

// AuthProxyWorkloadReconciler reconciles a AuthProxyWorkload object
type AuthProxyWorkloadReconciler struct {
client.Client
Scheme *runtime.Scheme
Scheme *runtime.Scheme
recentlyDeleted recentlyDeletedCache
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed.

func replaceCondition(conds []*metav1.Condition, newC *metav1.Condition) []*metav1.Condition {
for i := range conds {
c := conds[i]
if c.Type == newC.Type {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed.

@hessjcg hessjcg merged commit 0be2c0d into main Oct 7, 2022
@hessjcg hessjcg deleted the controller-logic branch October 7, 2022 19:51
This was referenced Oct 12, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants