-
Notifications
You must be signed in to change notification settings - Fork 594
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
Decoupling of Parser #822
Decoupling of Parser #822
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One more question: What is the rationale behind moving Consumer and KongState into their own dedicated packages?
In more detail: - create package KongState - move all the types (KongState as well as wrappers for kong.* types such as Service, Route, Upstream, etc) to package kongstate (to individual .go and _test.go files) - make functions that mutate the state of a wrapper (or a wrapped kong entity) a member function of the wrapper object (for Route, Service, Upstream). This required changes in tests: - to operate on the wrapper (e.g. kongstate.Route) - refactored assertions that calling methods on nil shall not panic instead of the wrapped type (kong.Route) - create package 'util' for helpers with no side effects
ee4590e
to
8f581ec
Compare
As discussed offline: it was the first type I moved and I didn't have a clear picture yet as to the target packages shape, so Consumer remained separate. Moved everything from |
This helps a lot with difficulty I've been having with the poor separation between the parser and store, especially with trying to write unit tests for them that aren't covering behavior that's sorta shared between them. Separating out the Kong state in particular should help enabling future work to generate config diffs for troubleshooting. My one note is that I'd caution against the use of acronyms or shorthand that aren't common elsewhere (e.g. "k8s" versus "Kubernetes" or "tech" versus "technology"). Those are harder to grasp when scanning through or reaching code via some path other than a straight readthrough (e.g. from a grep search or traceback, where I might start from somewhere in the middle rather than the start of a function): kubernetes-ingress-controller/internal/ingress/controller/parser/ingressrules.go Lines 58 to 72 in 7fdd505
kubernetes-ingress-controller/internal/ingress/controller/parser/kongstate/kongstate.go Line 119 in 7fdd505
kubernetes-ingress-controller/internal/ingress/controller/parser/kongstate/kongstate.go Lines 150 to 159 in 7fdd505
If the full names are getting egregiously long (4+ words or whatever as an arbitrary threshold), or it's something we need to use often (of the three, I'd argue "ks" is the most reasonable, since it's both used throughout that code and is an acronym for the main concept in that file), then we need to look at shortening, but otherwise, I'd suggest defaulting to the longer form. Non-blocking though: I was able to figure out the meaning in a couple seconds of looking back, but it was something where I needed to stop scanning and step back to look around for a bit. |
It is a Go idiom to name receivers with a one- or two-letter abbreviation of the receiver type name. I cannot say I wasn't surprised by this as I was switching from C++ to Go the other day. @rainest is that ok if we follow the convention for our projects, or would you like us to use longer receiver names? |
If it's idiomatic I'll note it down as "Go thing for receivers specifically, expect that in Go code in general"; TIL. |
Ingress V1: apiversion negotiation and flags, support in store, parser-k8s decoupling, ingress parsing refactor closes #788 This PR does the following (each high-level bullet point roughly matching a group of commits): - refactors `parseIngressRules` into separate functions (without side effects) and places them in `translate.go`: `fromIngressV1beta1` and `fromTCPIngressV1beta1`. Also moves `parseKnativeIngressRules` to follow suit. All of these get merged in the end using `mergeIngressRules` recently implemented in #822. - this comes with a tiny, potentially behavior changing, logic modification: after this PR, default backends get added to the overall set of `ingressRules` at a different stage of _"parsing"_ than they were before. - this change is here as a preparation for introduction of `fromIngressV1` which will be a copy-paste of `fromIngressV1beta1` with changes as described in the ingress v1 KEP. - removes concrete k8s types (`<your-favorite-apiversion>.Ingress`) and `TCPIngress` from `package kongstate` by introducing an intermediate `utils.K8sObjectInfo`: - I considered using k8s `ObjectMeta` instead of implementing `K8sObjectInfo` but that would violate separation between Kong and Kubernetes data formats that I wanted to achieve in `package kongstate`. - this change is here to accommodate Ingress V1. - reimplements Ingress API version negotiation: - to look not only at supported API groups, but also at the specific resource kind available in that API group (because `networking.k8s.io/v1` existed in k8s before the `Ingress` kind was added thereto) - to support `networking.k8s.io/v1` alongside the already supported versions - to support enabling and disabling support for specific APIs in Kong. This is for several reasons: - this PR does not implement Ingress V1 fully, so we can merge this PR in with ingress v1 code paths disabled - if Ingress V1 support is enabled in KIC, and the apiserver is >=1.19, then KIC will use a completely new code path in parser **for all preexisting Ingress resources**, posing a significant regression risk for existing users. There are two possible strategies for Ingress v1 rollout: - defensive: choose to leave ingress V1 APIs disabled by default - less defensive but with a workaround by design: make ingress V1 APIs enabled by default, but have the disabling flag readily at hand as a workaround for users whom we break - drive-by side effect: makes it possible to "soft-disable" extensions/v1beta1 ingress by setting its flag default to false - implements Ingress v1 alongside v1beta1 in store. - Note that the distinction between v1 and both v1beta1 types is implemented differently than between `extensions` and `networking` v1beta1. - This is because `extensions` and `networking` v1beta1 Ingresses are fully compatible, and they reuse the same parsing logic. Ingress V1, however, will be a separate implementation of the parsing logic. I wanted to ensure type safety (between v1beta1 and v1 ingresses), which would be impossible without differentiated storage. - additionally: adds `*.orig` to `.gitignore`. `*.orig` files originate from manually resolved Git conflicts and are easy to accidentally commit into the repo. Notes to the reviewer: - Consider reviewing commit by commit. - Commits are (intended to be) self-contained. Consider not squashing when merging. From #826
This is a refactoring PR for
package parser
inspired by my work on introducing Ingress v1 support. Its size may look intimidating, but when reviewed commit by commit, it should be easier to wrap one's head around the changes happening.Before this PR:
type Parser
had 26 member functions but did not hold any state,Service
,Route
,Upstream
etc. were mutable types, used as input+output arguments by free functions and methods ofParser
parser.go
(2005 LoC)Parser
could short-circuit the dependency graph of functions by making direct access tostore.Storer
.After this PR:
store.Storer
, now it does so through an argument. In several places, this PR decouples parsing logic fromstore.Storer
by replacing thestore.Storer
dependency with an actual batch of data. This is a preparation step for ingress v1: parse ingress class field in Ingress v1 resource #790 where the parsing logic will need to work with multiple presentation types for the same information.Service
,Route
,Upstream
, etc.) as well asKongState
, including their mutator functions, are moved to individual (smaller) files in packagekongstate
. The general idea (and long-term direction set forth by this PR) is to decouple Kubernetes presentation from Kong presentation by removing concrete Kubernetes types frompackage kongstate
. After this PR, we're still far from there yet. I plan to remove the concrete Ingress type frompackage kongstate
in Merge branch 'master' into 0.2.x #179.type Plugin
is almost decoupled - thekongPluginFromK8SPlugin
family of functions perform a clean transformation from one world (k8s entities) to the other (go-kong entities).Notes to reviewers:
kong.(Service|Route|Backend)
now operate onkongstate.(Service|Route|Backend)
,log
shadow function arguments namedlog
where they add fields to the logger. There's potential for repetition of the same field over and over by multiple functions on the call stack.nil
changed (expected to have no side effects),type ingressRules
and its merging logic (intended to yield identical results),