Skip to content

Conversation

@timraymond
Copy link
Member

The NMAgent client used previously in CNS is older, and a duplication of the one added in nmagent/. In order to maintain one nmagent client and prevent duplication / wasted effort, this changes CNS to use the "official" client instead.

Notes:

@timraymond timraymond requested a review from a team as a code owner October 3, 2022 18:44
@timraymond timraymond requested review from rbtr and removed request for a team October 3, 2022 18:45
@timraymond timraymond force-pushed the nma-switchover branch 3 times, most recently from 98e2d17 to 459a378 Compare October 17, 2022 22:57
rbtr
rbtr previously approved these changes Oct 18, 2022
var err error
joinResponse, joinErr := nmagent.JoinNetwork(networkID)
func (service *HTTPRestService) joinNetwork(ctx context.Context, networkID string) error {
jnr := nma.JoinNetworkRequest{
Copy link
Collaborator

Choose a reason for hiding this comment

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

Interesting that you abbreviate in this way. When I'm only dealing with a single request, I prefer using req, and imo that is the more common/readable pattern.

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... that's a habit I picked up from a C++ codebase lol. I like req too.

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, this was done in 7519cbd

fmt.Printf("Version %v\n", version)
}

type NodeInquirer interface {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm imagining this with a top hat and monocle. I would have gone with "Interrogator" 😅

Copy link
Member Author

Choose a reason for hiding this comment

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

I like Interrogator. I wanted to separate out the read ops from the write ops. NodeReader sounded... weird and misleading. Interrogator does say what it does what it says on the tin... it interrogates nodes for information. I guess that means the writing side should be NodeInceptor 😆

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 in 9381406

@timraymond timraymond requested a review from rbtr October 18, 2022 22:45
@timraymond timraymond enabled auto-merge (squash) October 18, 2022 22:45
@timraymond timraymond force-pushed the nma-switchover branch 2 times, most recently from 06a4ab1 to 992adda Compare October 19, 2022 14:26
This removes the PublishNetworkContainer method from the CNS client's
nmagent package in favor of using the one from the top-level nmagent
client package. This is to ensure that there's only one nmagent client
to maintain.
The existing unpublish endpoints within CNS used the older nmagent
client. This converts them to use the newer one.
The API in CNS was using the old nmagent client endpoints which we want
to phase out so that there is exactly one nmagent client across all
systems.
The CNS client uses this SupportedAPIs method to proxy requests from DNC
and detect capabilities of the node.
CNS previously used its own client method for accessing the GetNCVersion
endpoint of nmagent. In the interest of having a singular NMAgent
client, this adopts the behavior into the nmagent package and uses it
within CNS instead.
Checking whether the error was present and should it be present was
annoying and repetitive, so there's a helper now to take care of that.
Similarly, contexts are necessary but it's nice to create them from the
test's deadline itself. There's a helper to do that now as well.
There were some broken tests left over from implementing new NMAgent
interface methods. This makes those tests pass and also improves the
test suite by detangling mixed concerns of the utility functions within.
Many of them returned errors and made assertions, which made them
confusing to use. The utility functions now only do things you request,
and the tests themselves are the only ones making assertions (sometimes
through helpers that were added to make those assertions easier).
This is the final endpoint that was being used in CNS without being
present in the "official" NMAgent client. This moves that
implementation, more-or-less, to the nmagent package and consumes it in
NMAgent through an interface.
There were a few places where errors were shadowed. Also removed the
C-ism of pre-declaring variables for the sake of pre-declaring
variables.
In two instances, type assertions were used instead of errors.As. Apart
from being less obvious, there are apparently instances where this can
be incorrect with error wrapping.

Also, there was an instance where errors.As was mistakenly used in the
init clause of an if statement, instead of the predicate. This was
corrected to be a conjunctive predicate converting the error and then
making assertions using that error. This is safe because short-circuit
evaluation will prevent the second half of the predicate from being
evaluated if the error is not of that type.
The linter rightly pointed out that context could be trivially
propagated further than it was. This commit does exactly that.
The linter highlighted this error, showing that the error returned would
be confusing to a user of this function. This wraps the error indicating
that a join network request was issued at the point where the error was
produced, to aid in debugging.
This is really somewhat unnecessary because it's just a test. It
shouldn't impact correctness, since the errors were properly scoped to
their respective if statements. However, to prevent other people's
linters from complaining, this corrects the lint.
This is an unnecessary lint in a test, because it's useful to be able to
define errors on the fly when you need them in a test. However, the
linter demands it presently, so it must be silenced.
Surprisingly, a return was missing here. This was caught by the linter,
and was most certainly incorrect.
There was nothing incorrect about this shadowed err variable, but
linters complain about it and fail CI.
There were missing places where the nmagent client wasn't wired in
properly in main. This threads the client through completely and also
alters some tests to maintain compatibility.
This was in reaction to a lint detecting a vestigial use of
"WireserverIP". This package variable is no longer in use, however, the
spirit of it still exists. The changes adapt the provided configuration
into an nmagent.Config for use with the NMAgent Client instead.
The linter complained about a shadowed err, which is fine since it's
scoped in the `if`. Also there was a duplicate import which resulted
from refactoring. This has been de-duped.
The "jnr" variable was confusing when "req" is far more revealing of
what it is. Also, the "nma" alias was left over from a prior iteration
when the legacy nmagent package and the new one co-existed.
"Interrogator" is more revealing about the set of behavior encapsulated
by the interface. Depending on that behavior allows a consumer to
interrogate nodes for various information (but not modify anything about
them).
}

// NodeInterrogator is functionality necessary to read information about nodes.
// It is intended to be strictly read-only.
Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure I understand this line. Does it mean, not to expand the interface with methods that have side effects?

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, the intention is to set some opinions about what this set of behavior means. If you have some methods which aren't about digging information out of Nodes, then it might belong in another interface.

"github.com/Azure/azure-container-networking/cns/types"
"github.com/Azure/azure-container-networking/cns/wireserver"
"github.com/Azure/azure-container-networking/common"
nma "github.com/Azure/azure-container-networking/nmagent"
Copy link
Contributor

Choose a reason for hiding this comment

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

package is used as nmagent in other places, any reason to rename it in some places and not on others? personally, I think renaming packages should be done as little as possible. if it's widely understood that nma refers to nmagent, then the package should just be nma.

Copy link
Member Author

@timraymond timraymond Oct 19, 2022

Choose a reason for hiding this comment

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

Any instance of this is an oversight from when there were old and new packages both named nmagent. I agree, but I won't fix this in this PR because it is blocking other feature work. I'll add this to remediation items for a future PR.

req, _ = http.NewRequest(http.MethodPost, "", bytes.NewBuffer(body))
req.Header.Set(common.ContentType, common.JsonContent)

w := httptest.NewRecorder()
Copy link
Contributor

Choose a reason for hiding this comment

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

I know this is just moving existing lines, but this is... interesting, to say the least. i suppose its a symptom of all routing + business logic living in the same 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.

Not a fan of httptest in something that's not a test anyway... but that's a battle for another day.

return out, err // nolint:wrapcheck // wrapping just introduces noise here
}

// GetNetworkContainerVersion gets the current goal state version of a Network
Copy link
Contributor

Choose a reason for hiding this comment

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

godoc is off

Copy link
Member Author

Choose a reason for hiding this comment

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

Noted. Will fix in a future cleanup PR.

@timraymond timraymond merged commit 9cc0b0b into Azure:master Oct 19, 2022
@timraymond timraymond deleted the nma-switchover branch December 12, 2022 16:35
rjdenney pushed a commit to rjdenney/azure-container-networking that referenced this pull request Jan 19, 2023
…ge (Azure#1643)

* Switch PublishNetworkContainer to nmagent package

This removes the PublishNetworkContainer method from the CNS client's
nmagent package in favor of using the one from the top-level nmagent
client package. This is to ensure that there's only one nmagent client
to maintain.

* Use Unpublish method from nmagent package

The existing unpublish endpoints within CNS used the older nmagent
client. This converts them to use the newer one.

* Use JoinNetwork from new nmagent client

The API in CNS was using the old nmagent client endpoints which we want
to phase out so that there is exactly one nmagent client across all
systems.

* Add SupportedAPIs method to nmagent and use it

The CNS client uses this SupportedAPIs method to proxy requests from DNC
and detect capabilities of the node.

* Add GetNCVersion to nmagent and use it in CNS

CNS previously used its own client method for accessing the GetNCVersion
endpoint of nmagent. In the interest of having a singular NMAgent
client, this adopts the behavior into the nmagent package and uses it
within CNS instead.

* Use test helpers for context and checking errs

Checking whether the error was present and should it be present was
annoying and repetitive, so there's a helper now to take care of that.
Similarly, contexts are necessary but it's nice to create them from the
test's deadline itself. There's a helper to do that now as well.

* Fix broken tests & improve the suite

There were some broken tests left over from implementing new NMAgent
interface methods. This makes those tests pass and also improves the
test suite by detangling mixed concerns of the utility functions within.
Many of them returned errors and made assertions, which made them
confusing to use. The utility functions now only do things you request,
and the tests themselves are the only ones making assertions (sometimes
through helpers that were added to make those assertions easier).

* Add GetNCVersionList endpoint to NMAgent client

This is the final endpoint that was being used in CNS without being
present in the "official" NMAgent client. This moves that
implementation, more-or-less, to the nmagent package and consumes it in
NMAgent through an interface.

* Remove incorrect error shadowing

There were a few places where errors were shadowed. Also removed the
C-ism of pre-declaring variables for the sake of pre-declaring
variables.

* Replace error type assertions with errors.As

In two instances, type assertions were used instead of errors.As. Apart
from being less obvious, there are apparently instances where this can
be incorrect with error wrapping.

Also, there was an instance where errors.As was mistakenly used in the
init clause of an if statement, instead of the predicate. This was
corrected to be a conjunctive predicate converting the error and then
making assertions using that error. This is safe because short-circuit
evaluation will prevent the second half of the predicate from being
evaluated if the error is not of that type.

* Use context for joinNetwork

The linter rightly pointed out that context could be trivially
propagated further than it was. This commit does exactly that.

* Add error wrapping to an otherwise-opaque error

The linter highlighted this error, showing that the error returned would
be confusing to a user of this function. This wraps the error indicating
that a join network request was issued at the point where the error was
produced, to aid in debugging.

* Remove error shadowing in the tests

This is really somewhat unnecessary because it's just a test. It
shouldn't impact correctness, since the errors were properly scoped to
their respective if statements. However, to prevent other people's
linters from complaining, this corrects the lint.

* Silence complaints about dynamic errors in tests

This is an unnecessary lint in a test, because it's useful to be able to
define errors on the fly when you need them in a test. However, the
linter demands it presently, so it must be silenced.

* Add missing return for fmt.Errorf

Surprisingly, a return was missing here. This was caught by the linter,
and was most certainly incorrect.

* Remove yet another shadowed err

There was nothing incorrect about this shadowed err variable, but
linters complain about it and fail CI.

* Finish wiring in the NMAgent Client

There were missing places where the nmagent client wasn't wired in
properly in main. This threads the client through completely and also
alters some tests to maintain compatibility.

* Add config for Wireserver to NMAgent Client

This was in reaction to a lint detecting a vestigial use of
"WireserverIP". This package variable is no longer in use, however, the
spirit of it still exists. The changes adapt the provided configuration
into an nmagent.Config for use with the NMAgent Client instead.

* Silence the linter

The linter complained about a shadowed err, which is fine since it's
scoped in the `if`. Also there was a duplicate import which resulted
from refactoring. This has been de-duped.

* Rename jnr -> req and nma -> nmagent

The "jnr" variable was confusing when "req" is far more revealing of
what it is. Also, the "nma" alias was left over from a prior iteration
when the legacy nmagent package and the new one co-existed.

* Rename NodeInquirer -> NodeInterrogator

"Interrogator" is more revealing about the set of behavior encapsulated
by the interface. Depending on that behavior allows a consumer to
interrogate nodes for various information (but not modify anything about
them).
timraymond added a commit to timraymond/azure-container-networking that referenced this pull request Feb 24, 2023
This reverts commit 9cc0b0b.

Performing these changes uncovered unknown dependencies that clients had
on specific formations of responses from CNS. Until these can be
properly documented and understood, the legacy implementation must
remain.

A subsequent approach may instead introduce alternative endpoints with
known properties that clients can migrate to piecemeal.
timraymond added a commit to timraymond/azure-container-networking that referenced this pull request Feb 27, 2023
This reverts commit 9cc0b0b.

Performing these changes uncovered unknown dependencies that clients had
on specific formations of responses from CNS. Until these can be
properly documented and understood, the legacy implementation must
remain.

A subsequent approach may instead introduce alternative endpoints with
known properties that clients can migrate to piecemeal.
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.

4 participants